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

JavaScript Neednt Hurt - JavaBin talk

  • 1.
    JavaScript Needn’t Hurt! Thomas Kjeldahl Nilsson [email protected] linkedin.com/in/thomaskjeldahlnilsson twitter.com/thomanil
  • 4.
    What Are We CoveringToday? Language basics Html scripting Good practices Tools 10,000 ft view!
  • 5.
  • 7.
  • 8.
  • 9.
    (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)))
  • 10.
    (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)))
  • 11.
    What Sucks? Rushed out the door Some bad language features Crossbrowser problems
  • 12.
    What Rocks? Powerful, elegant, dynamic Present & enabled for most users Not confined to the browser Small learning surface
  • 13.
    Language Basics Syntax Types Variables Objects Functions
  • 14.
    Basic Syntax Similar to Java, C# Operators, statements if-else, while, for, try-catch-finally Still in Kansas...
  • 15.
    Types Strings Numbers Booleans Objects Arrays
  • 16.
    Variable Declarations var x = “foo”; // string var x = 2; // number var x = true; // boolean var x = { }; // object var x = [ ]; // array
  • 17.
  • 18.
    Object Creation Literal Form var basicProject = { name : "Steria Workshop", version : 1.2, getName : function() { return this.name; } };
  • 19.
    Object Creation Dynamic Form var basicProject = {}; basicProject.name = "Steria Workshop"; basicProject.version = 1.2; basicProject.getName = function() { return this.name; };
  • 20.
    Objects as Maps (Associative Arrays) var person = { firstname:"John", lastname:"Smith" }; person.firstname; // => "John" (Access using identifier) person["firstname"]; // => "John" (Access using variable name)
  • 21.
    Arrays and Objects Can Be Deeply Nested var outerObject = { innerArray : [ innerObject : { deepestArray : [1,2,3] } ] };
  • 22.
    JSON {"firstName":"Gustav","lastName":"Adolf", "roles":["King of Sweden","Terribleshipbuilder"], "other":{"birth":"9.12.1594","death":"16.11.1632"}}
  • 23.
    Kind Familiar Looking { "firstName" : "Gustav", "lastName" : "Adolf", "roles" : [ "King of Sweden", "Terrible shipbuilder" ], "other" : { "birth" : "9.12.1594", "death" : "16.11.1632" } }
  • 24.
    JavaScript Object Literal! var evaluatedObject = { firstName : "Gustav", lastName : "Adolf", roles : [ "King of Sweden", "Terrible shipbuilder" ], other : { birth : "9.12.1594", death : "16.11.1632" } };
  • 25.
  • 26.
  • 27.
    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
  • 28.
  • 29.
  • 30.
    Simple Function Definition function add(a, b) { return a + b; }
  • 31.
    Roughly Same Result: var add = function(a, b) { return a + b; }; // Use this consistently // Helps you remember: // Functions are just variables!
  • 32.
    An Anonymous Function... function(element) { // Do something with element }
  • 33.
    ...Can Be Sent ToAnother Function each(collection, function(element) { // Do something with current element });
  • 34.
    Example: Event Handler button.onClick(function(element) { alert(«You clicked me!»); });
  • 37.
    Sharp Edges Global variables No block scope Semicolon insertion == operator
  • 38.
    Properly Scoped Variable var getSmallNumber = function(){ var smallNumber = 42; // Note use of var keyword return smallNumber; };
  • 39.
    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
  • 40.
    No Block Scope varx = 1; if (true) { var x = 123; } // x => 123
  • 41.
    Semicolon insertion Don't force the browser to guess!
  • 42.
  • 43.
  • 44.
    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?
  • 45.
    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!
  • 46.
    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
  • 47.
    Clientside DOM scripting jQuery Firebug
  • 48.
  • 50.
    <TABLE> <TBODY> <TR> <TD>Shady Grove</TD> <TD>Aeolian</TD> </TR> <TR> <TD>Over the River, Charlie</TD> <TD>Dorian</TD> </TR> </TBODY> </TABLE>
  • 52.
    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
  • 53.
    DOM Api: Crossbrowser Headache http://www.quirksmode.org
  • 54.
  • 55.
  • 56.
    Instant Win: Crossbrowser Non-verbose Traverse DOM Manipulate DOM
  • 57.
    Lots of Other Stuff, Too Server communication UI widgets and effects each(), map(), etc JSON parsing +++
  • 58.
    jQuery Function $() // Short form jQuery() // Long form
  • 59.
    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
  • 60.
    $() Wraps andReturns Matching Element(s)
  • 61.
    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!”); });
  • 62.
    Chaining Every API call returns jQuery object So we can chain function calls together “Fluent API”
  • 63.
    Chaining Example // Setcolor on all paragraph elements, then hide them all $(“p”).css(”color”, ”green”).hide();
  • 64.
    Caution! Use frameworks asneeded But don't depend on them! JavaScript != jQuery
  • 65.
  • 66.
    Good Practices Firebug jsLint Unobtrusive JavaScript Automated testing
  • 68.
  • 70.
    Unobtrusive JavaScript Structure vs behavior Separate js files Event handler setup Namespaces Universal Access
  • 76.
    Namespace Hygiene All your code within single object
  • 77.
    Universal Access Can all your users use your site? Users without JS? Blind users with screen readers? Use progressive enhancement
  • 78.
    Crossbrowser Dev Process Frameworks > raw DOM Clean, disciplined code Test early, test often
  • 79.
    Automated Testing See the next talk... :)
  • 80.
  • 83.
    Web Resources http://javascript.crockford.com http://cjohansen.no/javascript http://ajaxian.com
  • 84.
    Best Way toLearn: Start Building! http://ajaxian.com/archives/writing-a-javascript-tetris-lessons-learned-from-a-ruby-chap
  • 85.
    Contact [email protected] linkedin.com/in/thomaskjeldahlnilsson twitter.com/thomanil

Editor's Notes