Skip to main content
JavaScript
Needn’t Hurt!
                 Thomas Kjeldahl Nilsson
              thomas@kjeldahlnilsson.net
    linkedin.com/in/thomaskjeldahlnilsson
                      twitter.com/thomanil
What Are We
Covering Today?
        Language basics
           Html scripting
          Good practices
                    Tools
          10,000 ft view!
History Lesson
Brendan Eich
2 WEEKS
(cond
 ((good? x)
  (handle-good x))
 ((bad? x)
  (handle-bad (if (really-bad? x)
                   (really-bad->bad x)
                   x)))
 ((ugly? x)
  (handle-ugly x))
 (else
  (handle-default x)))
(cond
 ((good? x)
  (handle-good x))
 ((bad? x)
  (handle-bad (if (really-bad? x)
                   (really-bad->bad x)
                   x)))
 ((ugly? x)
  (handle-ugly x))
 (else
  (handle-default x)))
What Sucks?
        Rushed out the door
 Some bad language features
    Crossbrowser problems
What Rocks?
     Powerful, elegant, dynamic
Present & enabled for most users
     Not confined to the browser
           Small learning surface
Language
   Basics
       Syntax
        Types
     Variables
       Objects
     Functions
Basic Syntax
                Similar to Java, C#
           Operators, statements
if-else, while, for, try-catch-finally
                   Still in Kansas...
Types
   Strings
 Numbers
 Booleans
  Objects
   Arrays
Variable
                    Declarations


var x = “foo”;   // string
var x = 2;       // number
var x = true;    // boolean
var x = { };     // object
var x = [ ];     // array
Objects
Object Creation
                         Literal Form
var basicProject = {

     name : "Steria Workshop",

     version : 1.2,

     getName : function() {
       return this.name;
     }

};
Object Creation
                   Dynamic Form


var basicProject = {};

basicProject.name = "Steria Workshop";
basicProject.version = 1.2;

basicProject.getName = function() {
   return this.name;
};
Objects as Maps
                       (Associative Arrays)


var person = { firstname:"John", lastname:"Smith" };

person.firstname;       // => "John" (Access using identifier)
person["firstname"];    // => "John" (Access using variable name)
Arrays and Objects
          Can Be Deeply Nested

var outerObject = {
   innerArray : [
     innerObject : {
        deepestArray : [1,2,3]
     }
   ]
};
JSON


{"firstName":"Gustav","lastName":"Adolf",
"roles":["King of Sweden","Terrible shipbuilder"],
"other":{"birth":"9.12.1594","death":"16.11.1632"}}
Kind Familiar Looking
{
    "firstName" : "Gustav",
    "lastName" : "Adolf",
    "roles" : [
          "King of Sweden",
          "Terrible shipbuilder"
     ],
    "other" : {
          "birth" : "9.12.1594",
          "death" : "16.11.1632"
     }
}
JavaScript
                                  Object Literal!
var evaluatedObject = {
   firstName : "Gustav",
   lastName : "Adolf",
   roles : [
         "King of Sweden",
         "Terrible shipbuilder"
     ],
   other : {
         birth : "9.12.1594",
         death : "16.11.1632"
     }
};
Inheritance
What is OOP?
Prototypal Inheritance
                                   (Simplified)
var employee = {name : "CEO Jack", company : "ACME Inc."};
var janitor = Object.create(employee);

// Janitor now looks and behaves just like its prototype, Employee
janitor.company // => "ACME Inc.", chains back to prototype.company

janitor.name = "Janitor Tim"; // Shadow name
janitor.tools = ["broom", "bucket"]; // Define member variable only on child

employee.name = "CEO Jane"; // Change name of prototype
janitor.name; // => Still "Janitor Tim". Shadowed members unaffected by prototype
    changes
Flexibility!
Functions
Simple Function
             Definition


function add(a, b) {
   return a + b;
}
Roughly Same Result:


 var add = function(a, b) {
    return a + b;
 };

 // Use this consistently
 // Helps you remember:
 // Functions are just variables!
An Anonymous
               Function...


function(element) {
   // Do something with element
}
...Can Be Sent
To Another Function


each(collection, function(element) {
    // Do something with current element
});
Example:
             Event Handler


button.onClick(function(element) {
    alert(«You clicked me!»);
});
Sharp Edges
      Global variables
       No block scope
    Semicolon insertion
           == operator
Properly Scoped
                           Variable


var getSmallNumber = function(){
   var smallNumber = 42; // Note use of var keyword
   return smallNumber;
};
Sloppy,
                       Global Variable


var getSmallNumber = function(){
   smallNumber = 42;
   return smallNumber;
};

// Missing var prefix = smallNumber gets global scope
// Becomes available for all code
// Sticks around and pollutes namespace
No Block Scope


var x = 1;

if (true) {
   var x = 123;
}

// x => 123
Semicolon
       insertion
Don't force the browser to guess!
Example


a=b+c
(d + e).print()

becomes...

a = b + c(d + e).print();
== vs ===
Quiz

'' == '0'            // true or false?
0 == ''              // true or false?
0 == '0'             // true or false?
false == 'false'     // true or false?
false == '0'         // true or false?
false == undefined   // true or false?
false == null        // true or false?
null == undefined    // true or false?
' trn ' == 0      // true or false?
How Many
                       Did You Get?

'' == '0'               // false
0 == ''                 // true
0 == '0'                // true
false == 'false'        // false
false == '0'            // true
false == undefined      // false
false == null           // false
null == undefined       // true
' trn ' == 0         // true

// Why? Type coercion on right operand!
Instead, Use ===
                      (And !==)

'' === '0'            // false
0 === ''              // false
0 === '0'             // false
false === 'false'     // false
false === '0'         // false
false === undefined   // false
false === null        // false
null === undefined    // false
' trn ' === 0      // false
Clientside
    DOM scripting
          jQuery
         Firebug
The DOM
<TABLE>
    <TBODY>
       <TR>
          <TD>Shady Grove</TD>
          <TD>Aeolian</TD>
       </TR>
       <TR>
          <TD>Over the River, Charlie</TD>
          <TD>Dorian</TD>
       </TR>
    </TBODY>
</TABLE>
DOM Scripting
                                          Basics

x.getElementById(id) ;               // get the element with a specified id

x.getElementsByTagName(name);        // get all elements with a
                                                   // specified tag name

x.appendChild(node);                 // insert a child node to x
x.removeChild(node),                 // remove a child node from x

x.innerHTML = «<p>New text</p>»; // fill element with html or text
DOM Api:
Crossbrowser Headache




            http://www.quirksmode.org
Use Frameworks
jQuery
Instant Win:
       Crossbrowser
        Non-verbose
      Traverse DOM
     Manipulate DOM
Lots of Other
   Stuff, Too
    Server communication
    UI widgets and effects
        each(), map(), etc
            JSON parsing
                      +++
jQuery Function



$()        // Short form
jQuery()   // Long form
Find Stuff


$(“p”);                 // Find all paragraphs
$(“#shoppingList”);     // Find element with id 'shoppingList'
$(“.shoppingListItem”); // Find elements with class 'shoppingListItem'
$(“:text”);             // Find all text elements
$(“:visible”);          // Find only visible elements
$() Wraps and Returns
  Matching Element(s)
Manipulate Matched
                               DOM Elements


$(“p”).css(”color”, ”green”);    // Set color on all paragraph elements
$(“p”).hide();                   // Hide all paragraphs

// Make all input buttons react to mouse clicks
$(“input”).click(function(){ alert(”You clicked this button!”); });
Chaining
   Every API call returns jQuery object
So we can chain function calls together
                           “Fluent API”
Chaining Example


// Set color on all paragraph elements, then hide them all
$(“p”).css(”color”, ”green”).hide();
Caution!
Use frameworks as needed
 But don't depend on them!
       JavaScript != jQuery
Example
Good Practices
                   Firebug
                      jsLint
     Unobtrusive JavaScript
         Automated testing
JsLint
Unobtrusive
 JavaScript
   Structure vs behavior
        Separate js files
    Event handler setup
           Namespaces
       Universal Access
Namespace
    Hygiene
All your code within single object
Universal
          Access
Can all your users use your site?
               Users without JS?
Blind users with screen readers?
  Use progressive enhancement
Crossbrowser
 Dev Process
   Frameworks > raw DOM
    Clean, disciplined code
       Test early, test often
Automated
   Testing
  See the next talk... :)
References &
Further Study
Web Resources
   http://javascript.crockford.com
    http://cjohansen.no/javascript
                http://ajaxian.com
Best Way to Learn:

                                            Start Building!




http://ajaxian.com/archives/writing-a-javascript-tetris-lessons-learned-from-a-ruby-chap
Contact Infothomas@kjeldahlnilsson.net
  linkedin.com/in/thomaskjeldahlnilsson
                    twitter.com/thomanil