A Reintroduction to Javascript 4633

Embed Size (px)

Citation preview

  • 8/8/2019 A Reintroduction to Javascript 4633

    1/111

    1

    A (Re)-Introduction to JavaScript

    Simon Willison ETech, March 6th, 2005

    http://www.flickr.com/photos/tomsly/93947243/ - thomas_sly

    1

    http://www.flickr.com/photos/tomsly/93947243/http://www.flickr.com/photos/tomsly/93947243/
  • 8/8/2019 A Reintroduction to Javascript 4633

    2/111

    Coming up...

    2

    Numbers, Strings and things

    Variables and Operators

    Control Structures

    Objects and Arrays

    Functions

    Object constructors and inheritance

    Inner functions and closures

    Memory Leaks... and more

    2

  • 8/8/2019 A Reintroduction to Javascript 4633

    3/111

    Book recommendation

    JavaScript: TheDefinitive Guide

    by David Flanagan

    Comprehensiveoverview of thelanguage in the first

    20 chapters New edition out later

    this year

    3

    3

  • 8/8/2019 A Reintroduction to Javascript 4633

    4/111

    More book recommendations

    For practical applications of this stuff:

    4

    4

  • 8/8/2019 A Reintroduction to Javascript 4633

    5/111

    You will need...

    5

    Firefox Any web browser can run JavaScript, but

    Firefox has the best tools for developers

    Jesse Ruderman's 'shell' tool

    http://www.squarefree.com/shell/

    A text editor may come in handy too

    5

    http://www.squarefree.com/shell/http://www.squarefree.com/shell/http://www.squarefree.com/shell/
  • 8/8/2019 A Reintroduction to Javascript 4633

    6/111

    In the words of its creator

    6

    JavaScript was a rushed little hack forNetscape 2 that was then frozen prematurely

    during the browser wars, and evolved

    significantly only once by ECMA. So its earlyflaws were never fixed, and worse, novirtuous cycle of fine-grained community

    feedback in the form of standard library code

    construction, and revision of the foundationalparts of the language to better support thestandard library and its common use-cases,

    ever occurred.http://weblogs.mozillazine.org/roadmap/archives/2006/02/js_and_python_news.html

    6

    http://weblogs.mozillazine.org/roadmap/archives/2006/02/js_and_python_news.htmlhttp://weblogs.mozillazine.org/roadmap/archives/2006/02/js_and_python_news.htmlhttp://weblogs.mozillazine.org/roadmap/archives/2006/02/js_and_python_news.html
  • 8/8/2019 A Reintroduction to Javascript 4633

    7/111

    7

    (in 30 seconds)

    The History of JavaScript

    http://www.flickr.com/photos/kingcoyote/93491484/ - King Coyote

    7

    http://www.flickr.com/photos/kingcoyote/93491484/http://www.flickr.com/photos/kingcoyote/93491484/
  • 8/8/2019 A Reintroduction to Javascript 4633

    8/111

    JavaScript was...

    8

    Invented by Brendan Eich in 1995 forNetscape; originally called LiveScript, current

    name being an ill-fated marketing decision totie in with Sun's newly released Java;

    adapted by Microsoft as JScript for IE 3 in

    1996; standardised as ECMAScript in 1997;sort-of included in Flash as ActionScript;updated to ECMAScript 3rd edition in 1998

    8

  • 8/8/2019 A Reintroduction to Javascript 4633

    9/111

    Not quite general purpose

    No direct concept of input or output Runs within a host environment

    Web browser

    Adobe Acrobat

    Photoshop

    Windows Scripting Host Yahoo! Widget Engine

    and more...

    9

    9

    h // fli k / h / li / / B i S

    http://www.flickr.com/photos/olivepress/11223013/
  • 8/8/2019 A Reintroduction to Javascript 4633

    10/111

    Syntax

    http://www.flickr.com/photos/olivepress/11223013/ - Brian Sawyer

    10

    http://www.flickr.com/photos/olivepress/11223013/http://www.flickr.com/photos/olivepress/11223013/
  • 8/8/2019 A Reintroduction to Javascript 4633

    11/111

    Reserved words

    break else new varcase finally return voidcatch for switch while

    continue function this withdefault if throw

    delete in trydo instanceof typeof

    abstract enum int shortboolean export interface static

    byte extends long super

    char final native synchronizedclass float package throws

    const goto private transientdebugger implements protected volatile

    double import public

    11

    11

  • 8/8/2019 A Reintroduction to Javascript 4633

    12/111

    Style recommendations

    Avoid semi-colon insertion like the plague

    ; ; ; friends Declare variables religiously with 'var'

    Global variables are evil. Avoid them if you

    can. Indent consistently

    12

    12

    h // fli k / h /k i h/64919318/ K' i h / H h H hi

    http://www.flickr.com/photos/kvitsh/64919318/
  • 8/8/2019 A Reintroduction to Javascript 4633

    13/111

    13

    Types

    http://www.flickr.com/photos/kvitsh/64919318/ - K'vitsh / Heather Hutchinson

    13

    http://www.flickr.com/photos/kvitsh/64919318/http://www.flickr.com/photos/kvitsh/64919318/
  • 8/8/2019 A Reintroduction to Javascript 4633

    14/111

    JavaScript types

    14

    Numbers Strings

    Booleans

    Functions

    Objects

    14

  • 8/8/2019 A Reintroduction to Javascript 4633

    15/111

    JavaScript types (improved)

    Number String

    Boolean

    ObjectFunction

    Array

    Date

    RegExp

    Null

    Undefined15

    15

    http://www flickr com/photos/51035555243@N01/72778694/ Thomas Hawk

    http://www.flickr.com/photos/51035555243@N01/72778694/
  • 8/8/2019 A Reintroduction to Javascript 4633

    16/111

    16

    Numbers

    http://www.flickr.com/photos/51035555243@N01/72778694/ - Thomas Hawk

    16

    http://www.flickr.com/photos/51035555243@N01/72778694/http://www.flickr.com/photos/51035555243@N01/72778694/
  • 8/8/2019 A Reintroduction to Javascript 4633

    17/111

    Numbers

    17

    "double-precision 64-bit format IEEE 754values"

    No such thing as an integer

    0.1 + 0.2 = 0.30000000000000004

    3 + 5.3

    28 % 6 etc... Math namespace for advanced operations

    17

  • 8/8/2019 A Reintroduction to Javascript 4633

    18/111

    Math stuff

    Math.PI, Math.E, Math.LN10,Math.LN2, Math.LOG10E,Math.SQRT1_2, Math.SQRT2

    Math.abs(x), Math.acos(x),Math.asin(x), Math.atan(x),

    Math.atan2(y, x),Math.ceil(x),Math.cos(x), Math.exp(x),

    Math.floor(x), Math.log(x),Math.max(x, ..),Math.min(x, ..),Math.pow(x, y),Math.random(),Math.round(x), Math.sin(x),

    Math.sqrt x , Math.tan x1818

  • 8/8/2019 A Reintroduction to Javascript 4633

    19/111

    parseInt (and parseFloat)

    parseInt converts a string to a number> parseInt("123");123

    > parseInt("010");8

    !?

    > parseInt("010", 10);10> parseInt("11", 2)3

    19

    Always specify the base

    19

  • 8/8/2019 A Reintroduction to Javascript 4633

    20/111

    NaN and Infinity

    > parseInt("hello", 10)NaN

    NaN is toxic

    > NaN + 5NaN> isNaN(NaN)true

    Special values for Infinity and -Infinity:

    > 1 / 0Infinity

    20

    > -1 / 0-Infinity

    20

    http://www flickr com/photos/solarider/53494967/ - solarider

    http://www.flickr.com/photos/solarider/53494967/
  • 8/8/2019 A Reintroduction to Javascript 4633

    21/111

    21

    Strings

    http://www.flickr.com/photos/solarider/53494967/ solarider

    21

    http://www.flickr.com/photos/solarider/53494967/http://www.flickr.com/photos/solarider/53494967/
  • 8/8/2019 A Reintroduction to Javascript 4633

    22/111

    Strings

    22

    Sequences of characters Sequences ofunicode characters (16 bit)

    "\u0020"

    A character is a string of length 1

    > "hello".length

    5 Strings are objects!

    22

  • 8/8/2019 A Reintroduction to Javascript 4633

    23/111

    String methods

    > "hello".charAt(0)h

    > "hello, world".replace("hello",

    "goodbye")

    goodbye, world

    > "hello".toUpperCase()

    HELLO

    23

    23

  • 8/8/2019 A Reintroduction to Javascript 4633

    24/111

    More string methods

    s.charAt(pos) s.charCodeAt(pos)s.concat(s1, ..)

    s.indexOf(s1, start)

    s.lastIndexOf(s1, startPos)s.localeCompare(s1) s.match(re)s.replace(search, replace)

    s.search(re) s.slice(start, end)

    s.split(separator, limit)s.substring(start, end)

    s.toLowerCase() s.toLocaleLowerCase()

    s.toUpperCase() s.toLocaleUpperCase()2424

  • 8/8/2019 A Reintroduction to Javascript 4633

    25/111

    Null and undefined

    null = deliberately no value undefined = no value assigned yet

    Variables declared but not initialised

    Object/array members that don't exist

    (More on this later)

    25

    25

  • 8/8/2019 A Reintroduction to Javascript 4633

    26/111

    Booleans

    Boolean type: true or false Everything else is "truthy" or "falsy"

    0, "", NaN, null, undefinedare falsy

    Everything else is truthy

    Boolean operations: &&, || and !

    Convert any value to it's boolean equivalentby applying not twice:

    > !!""

    false26

    > !!234

    true26

    http://www.flickr.com/photos/antmoose/71277315/ - antmoose / Anthony M.

    http://www.flickr.com/photos/antmoose/71277315/http://www.flickr.com/photos/antmoose/71277315/
  • 8/8/2019 A Reintroduction to Javascript 4633

    27/111

    27

    Variables and operators

    27

  • 8/8/2019 A Reintroduction to Javascript 4633

    28/111

    Variable declaration

    28

    New variables in JavaScript are declaredusing the var keyword:

    var a;

    var name = "simon";

    If you declare a variable without assigning itto anything, its value is undefined.

    If you forget the var, you get a globalvariable. Never, ever do this - not even ifyou mean it.

    28

  • 8/8/2019 A Reintroduction to Javascript 4633

    29/111

    Operators

    Numeric operators: +, -, *, / and % Compound assignment operators:

    +=, -=, *=, /=, %=

    Increment and decrement:

    a++, ++a, b--, --b

    String concatenation:> "hello" + " world"

    hello world29

    29

  • 8/8/2019 A Reintroduction to Javascript 4633

    30/111

    Type coercion

    > "3" + 4 + 5345

    > 3 + 4 + "5"

    75

    Adding an empty string to something elseconverts it to a string.

    30

    30

  • 8/8/2019 A Reintroduction to Javascript 4633

    31/111

    Comparison

    >, =, "dog" == "dog"

    true> 1 == truetrue

    === and !== avoid type coercion

    > 1 === truefalse> true === true

    true3131

  • 8/8/2019 A Reintroduction to Javascript 4633

    32/111

    The typeof operator

    typeof v

    32

    number 'number'

    string 'string'

    boolean 'boolean'

    function 'function'

    object 'object'

    array 'object'

    null 'object'

    undefined 'undefined'

    32

    http://www.flickr.com/photos/setre/8825214/ - setre

    http://www.flickr.com/photos/setre/8825214/http://www.flickr.com/photos/setre/8825214/
  • 8/8/2019 A Reintroduction to Javascript 4633

    33/111

    33

    Control structures

    33

  • 8/8/2019 A Reintroduction to Javascript 4633

    34/111

    if statements

    34

    var name = "kittens";if (name == "puppies") {

    name += "!";

    } else if (name == "kittens") {name += "!!";

    } else {

    name = "!" + name;}

    name == "kittens!!"

    34

  • 8/8/2019 A Reintroduction to Javascript 4633

    35/111

    while and do-while

    while (true) {// an infinite loop!

    }

    do {

    var input = get_input();} while (inputIsNotValid(input))

    35

    35

  • 8/8/2019 A Reintroduction to Javascript 4633

    36/111

    for loops

    for (var i = 0; i < 5; i++) {// Will execute 5 times

    }

    36

    36

  • 8/8/2019 A Reintroduction to Javascript 4633

    37/111

    switch statement

    Multiple branches depending on a number orstring

    switch(action) {

    case 'draw':drawit();break;

    case 'eat':eatit();break;

    default:donothing();

    }37

    37

  • 8/8/2019 A Reintroduction to Javascript 4633

    38/111

    fall through

    switch(a) {case 1: // fallthroughcase 2:

    eatit();

    break;default:donothing();

    }

    Deliberate labelling of fall through is goodpractise

    38

    38

  • 8/8/2019 A Reintroduction to Javascript 4633

    39/111

    Switch expressions

    Expressions are allowed Comparisons take place using ===

    switch(1 + 3):

    case 2 + 2:yay();

    break;

    default:neverhappens();

    }

    39

    39

  • 8/8/2019 A Reintroduction to Javascript 4633

    40/111

    Short-circuit logic

    The && and || operators use short-circuitlogic: they will execute their second operanddependant on the first.

    This is useful for checking for null objectsbefore accessing their attributes:

    var name = o && o.getName();

    Or for setting default values:

    var name = otherName || "default";

    40

    40

  • 8/8/2019 A Reintroduction to Javascript 4633

    41/111

    The tertiary operator

    One-line conditional statementsvar ok = (age > 18) ? "yes" : "no";

    Easy to abuse; use with caution

    41

    41

  • 8/8/2019 A Reintroduction to Javascript 4633

    42/111

    Exceptions

    try {// Statements in which// exceptions might be thrown

    } catch(error) {// Statements that execute

    // in the event of an exception} finally {// Statements that execute// afterward either way

    }

    throw new Error("An error!");throw "Another error!";

    42

    42

    http://www.flickr.com/photos/spengler/51617271/ - Andreas D.

    http://www.flickr.com/photos/spengler/51617271/http://www.flickr.com/photos/spengler/51617271/
  • 8/8/2019 A Reintroduction to Javascript 4633

    43/111

    43

    Objects

    43

  • 8/8/2019 A Reintroduction to Javascript 4633

    44/111

    Objects

    44

    Simple name-value pairs, as seen in: Dictionaries in Python

    Hashes in Perl and Ruby

    Hash tables in C and C++

    HashMaps in Java

    Associative arrays in PHP

    Very common, versatile data structure

    Name part is a string; value can be anything

    44

  • 8/8/2019 A Reintroduction to Javascript 4633

    45/111

    Basic object creation

    var obj = new Object(); Or:

    var obj = {};

    These are semantically equivalent; thesecond is called object literal syntax and ismore convenient.

    45

    45

    P

  • 8/8/2019 A Reintroduction to Javascript 4633

    46/111

    Property access

    obj.name = "Simon"var name = obj.name;

    Or...

    obj["name"] = "Simon";

    var name = obj["name"];

    Semantically equivalent; the second usesstrings so can be decided at run-time (andcan be used for reserved words)

    46

    46

    Obj t lit l t

  • 8/8/2019 A Reintroduction to Javascript 4633

    47/111

    Object literal syntax

    var obj = {name: "Carrot","for": "Max",details: {

    color: "orange",size: 12

    }}

    > obj.details.colororange

    47

    > obj["details"]["size"]

    12

    47

    f ( tt i bj)

  • 8/8/2019 A Reintroduction to Javascript 4633

    48/111

    for (var attr in obj)

    You can iterate over the keys of an object:var obj = { 'name': 'Simon', 'age': 25};

    for (var attr in obj) {

    print (attr + ' = ' + obj[attr]);}

    Don't attempt this with arrays (coming up

    next). There are safer ways of iterating overthem.

    48

    48

    http://www.flickr.com/photos/adrian_s/28567268/ - waffler / Adrian Sampson

    http://www.flickr.com/photos/adrian_s/28567268/http://www.flickr.com/photos/adrian_s/28567268/
  • 8/8/2019 A Reintroduction to Javascript 4633

    49/111

    49

    Arrays

    49

    A

  • 8/8/2019 A Reintroduction to Javascript 4633

    50/111

    Arrays

    50

    A special type of object: Keys are wholenumbers, not strings.

    Use [] syntax, just like objects

    > var a = new Array();

    > a[0] = "dog";

    > a[1] = "cat";

    > a[2] = "hen";

    > a.length

    350

    A lit l

  • 8/8/2019 A Reintroduction to Javascript 4633

    51/111

    Array literals

    More convenient notation:> var a = ["dog", "cat", "hen"];

    > a.length

    3

    51

    51

    l th

  • 8/8/2019 A Reintroduction to Javascript 4633

    52/111

    array.length

    > var a = ["dog", "cat", "hen"];> a[100] = "fox";

    > a.length

    101

    typeof a[90] == 'undefined'

    array.length is always one more than thehighest index

    The safest way to append new items is:

    a[a.length] = item;5252

    A it ti

  • 8/8/2019 A Reintroduction to Javascript 4633

    53/111

    Array iteration

    for (var i = 0; i < a.length; i++) {// Do something with a[i]

    }

    Improve this by caching a.length at start:

    for (var i = 0, j = a.length; i < j; i++) {

    // Do something with a[i]

    }53

    53

    E b tt it ti

  • 8/8/2019 A Reintroduction to Javascript 4633

    54/111

    Even better iteration

    for (var i = 0, item; item = a[i]; i++) {// Do something with item

    }

    This trick only works with arrays that areknown not to contain falsy values. Thefollowing array will break with the above

    idiom:var a = [10, "dog", false, "elephant"];

    (Yes, you can have mixed content in arrays)

    54

    54

    A th d

  • 8/8/2019 A Reintroduction to Javascript 4633

    55/111

    Array methods

    a.toString(), a.toLocaleString(),a.concat(item, ..), a.join(sep), a.pop(),a.push(item, ..), a.reverse(), a.shift(),

    a.slice(start, end), a.sort(cmpfn),a.splice(start, delcount, [item]..),

    a.unshift([item]..)

    55

    55

    3.2

  • 8/8/2019 A Reintroduction to Javascript 4633

    56/111

    .8 -4 -3.2 -2.4 -1.6 -0.8 0 0.8 1.6 2.4 3.2 4 4.8

    -3.2

    -2.4

    -1.6

    -0.8

    0.8

    1.6

    2.4

    56

    Functions

    56

    Functions

  • 8/8/2019 A Reintroduction to Javascript 4633

    57/111

    Functions

    57

    Don't get much simpler than this:function add(x, y) {

    var total = x + y;

    return total;

    }

    If nothing is explicitly returned, return value is

    undefined

    57

    Arguments

  • 8/8/2019 A Reintroduction to Javascript 4633

    58/111

    Arguments

    Parameters: "They're more like... guidelines" Missing parameters are treated as undefined:

    > add()

    Nan // addition on undefined

    You can pass in more arguments thanexpected:

    > add(2, 3, 4)5 // added the first two; 4 was ignored

    How is this behaviour useful?58

    58

    arguments

  • 8/8/2019 A Reintroduction to Javascript 4633

    59/111

    arguments

    The arguments special variable providesaccess to arguments as an array-like objectfunction add() {

    var sum = 0;

    for (var i = 0, j = arguments.length;i < j; i++) {sum += arguments[i];

    }return sum;

    }

    > add(2, 3, 4, 5)14

    59

    59

    avg()

  • 8/8/2019 A Reintroduction to Javascript 4633

    60/111

    avg()

    More useful: an averaging function:function avg() {

    var sum = 0;

    for (var i = 0, j = arguments.length;

    i < j; i++) {

    sum += arguments[i];

    }

    return sum / arguments.length;

    }

    60

    60

    Averaging an array?

  • 8/8/2019 A Reintroduction to Javascript 4633

    61/111

    Averaging an array?

    Our fancy multi-argument function isn't muchgood if our data is already in an array. Do wehave to rewrite it?

    function avgArray(arr) {var sum = 0;for (var i = 0, j = arr.length;

    i < j; i++) {sum += arguments[i];

    }return sum / arr.length;

    }

    61

    61

    Using avg() with an array

  • 8/8/2019 A Reintroduction to Javascript 4633

    62/111

    Using avg() with an array

    That's not necessary:> avg.apply(null, [2, 3, 4, 5])

    3.5

    Functions are objects with methods too!

    The apply method takes an array ofargments as the second argument...

    We'll find out about the first argument a littlelater

    62

    62

    Anonymous functions

  • 8/8/2019 A Reintroduction to Javascript 4633

    63/111

    Anonymous functions

    The following is semantically equivalent toour earlier avg() function:

    var avg = function() {

    var sum = 0;

    for (var i = 0, j = arguments.length;

    i < j; i++) {

    sum += arguments[i];

    }

    return sum / arguments.length;

    }

    63

    63

    The block scope trick

  • 8/8/2019 A Reintroduction to Javascript 4633

    64/111

    The block scope trick

    Block scope is a feature of C where everyset of braces defines a new scope. It can besimulated in JavaScript:

    var a = 1;var b = 2;(function() {

    var b = 3;a += b;

    })();> a4> b

    26464

    Recursive functions

  • 8/8/2019 A Reintroduction to Javascript 4633

    65/111

    Recursive functions

    function countChars(elm) {if (elm.nodeType == 3) { // TEXT_NODE

    return elm.nodeValue.length;

    }

    var count = 0;for (var i = 0, child;

    child = elm.childNodes[i]; i++) {

    count += countChars(child);}

    return count;

    }

    65

    65

    arguments callee

  • 8/8/2019 A Reintroduction to Javascript 4633

    66/111

    arguments.callee

    arguments.callee is the current function:var charsInBody = (function(elm) {if (elm.nodeType == 3) { // TEXT_NODE

    return elm.nodeValue.length;

    }var count = 0;

    for (var i = 0, child;

    child = elm.childNodes[i]; i++) {

    count += arguments.callee(child);

    }

    return count;

    document.bod ;6666

    arguments callee to save state

  • 8/8/2019 A Reintroduction to Javascript 4633

    67/111

    arguments.callee to save state

    This function remembers how many times ithas been called:function counter() {

    if (!arguments.callee.count) {

    arguments.callee.count = 0;}return arguments.callee.count++;

    }

    > counter()0> counter()1

    67

    67

    http://www.flickr.com/photos/45339031@N00/100472474/ - piccadillywilson / Matt

    http://www.flickr.com/photos/45339031@N00/100472474/http://www.flickr.com/photos/45339031@N00/100472474/
  • 8/8/2019 A Reintroduction to Javascript 4633

    68/111

    68

    Constructors

    68

    Functions and objects

  • 8/8/2019 A Reintroduction to Javascript 4633

    69/111

    Functions and objects

    69

    function makePerson(first, last) {return {

    first: first,last: last

    }

    }function personFullName(person) {

    return person.first + ' ' +person.last;

    }function personFullNameReversed(person) {

    return person.last + ', ' +person.first

    }

    69

    Functions and objects (II)

  • 8/8/2019 A Reintroduction to Javascript 4633

    70/111

    Functions and objects (II)

    > s = makePerson("Simon","Willison");

    > personFullName(s)

    Simon Willison> personFullNameReversed(s)

    Willison, Simon

    Surely we can attach functions to the objectsthemselves?

    70

    70

    Methods first try

  • 8/8/2019 A Reintroduction to Javascript 4633

    71/111

    Methods, first try

    function makePerson(first, last) {return {first: first,last: last,fullName: function() {

    return this.first + ' ' +this.last;

    },fullNameReversed: function() {

    return this.last + ', ' +this.first;}

    }}

    71

    71

    Using methods

  • 8/8/2019 A Reintroduction to Javascript 4633

    72/111

    Using methods

    > s = makePerson("Simon","Willison")

    > s.fullName()

    Simon Willison> s.fullNameReversed()

    Willison, Simon

    72

    72

    dot notation is required

  • 8/8/2019 A Reintroduction to Javascript 4633

    73/111

    dot notation is required

    > s = makePerson("Simon","Willison")

    > var fullName = s.fullName;

    > fullName()undefined undefined

    If you call a function without using dot

    notation, 'this' is set to the global object. Inthe browser, this is the same as 'window'.

    73

    73

    Constructors

  • 8/8/2019 A Reintroduction to Javascript 4633

    74/111

    Constructors

    function Person(first, last) {this.first = first;this.last = last;this.fullName = function() {return this.first + ' ' +

    this.last;}this.fullNameReversed = function() {return this.last + ', ' +this.first;

    }}

    var s = new Person("Simon", "Willison");

    74

    74

    new

  • 8/8/2019 A Reintroduction to Javascript 4633

    75/111

    new

    'new' creates a new empty object and callsthe specified function with 'this' set to thatobject.

    These constructor functions should beCapitalised, as a reminder that they aredesigned to be called using 'new'

    This is key to understanding JavaScript'sobject model

    75

    75

    Sharing methods

  • 8/8/2019 A Reintroduction to Javascript 4633

    76/111

    Sharing methods

    function personFullName() {return this.first + ' ' +this.last;

    }function personFullNameReversed() {

    return this.last + ', ' +this.first;}function Person(first, last) {

    this.first = first;this.last = last;this.fullName = personFullName;this.fullNameReversed =

    personFullNameReversed;

    }7676

    Person.prototype

  • 8/8/2019 A Reintroduction to Javascript 4633

    77/111

    Person.prototype

    function Person(first, last) {this.first = first;this.last = last;

    }Person.prototype.fullName =

    function() {return this.first + ' ' +this.last;

    }Person.prototype.fullNameReversed =function() {

    return this.last + ', ' +this.first;

    }

    77

    77

    instanceof

  • 8/8/2019 A Reintroduction to Javascript 4633

    78/111

    instanceof

    The instanceof operator can be used to testthe type of an object, based on itsconstructor (and prototype hierarchy,explained in the next section).

    var a = [1, 2, 3];a instanceof Arraytrue

    a instanceof Objecttruea instanceof String

    false78

    78

    http://www.flickr.com/photos/bingolittle/5803243/ - Bingo Little

    http://www.flickr.com/photos/bingolittle/5803243/http://www.flickr.com/photos/bingolittle/5803243/
  • 8/8/2019 A Reintroduction to Javascript 4633

    79/111

    79

    Inheritance

    79

    Adding to an existing set of objects

  • 8/8/2019 A Reintroduction to Javascript 4633

    80/111

    Adding to an existing set of objects

    > s = new Person("Simon","Willison");> s.firstNameCaps();TypeError on line 1:

    s.firstNameCaps is not a function

    > Person.prototype.firstNameCaps =function() {

    return this.first.toUpperCase()}> s.firstNameCaps()SIMON

    80

    80

    Extending core objects

  • 8/8/2019 A Reintroduction to Javascript 4633

    81/111

    te d g co e objects

    > var s = "Simon";> s.reversed()TypeError: s.reversed is not a function

    > String.prototype.reversed = function() {var r = '';

    for (var i = this.length - 1; i >= 0; i--){r += this[i];

    }return r;

    }

    > s.reversed()nomiS> "This can now be reversed".reversed()

    desrever eb won nac sihT81

    81

    Object.prototype

  • 8/8/2019 A Reintroduction to Javascript 4633

    82/111

    j p yp

    All prototype chains terminate atObject.prototype

    Its methods include toString(), which we can

    over-ride:> var s = new Person("Simon", "Willison");> s[object Object]> Person.prototype.toString = function() {

    return '';}> s

    82

    82

    Perils of modifying Object.prototype

  • 8/8/2019 A Reintroduction to Javascript 4633

    83/111

    y g j p yp

    Remember for (var attr in obj)? It will include stuff that's been newly added to

    Object.prototype

    This stupid behaviour is sadly baked in to thelanguage

    Some libraries (Prototype is a prime

    offender) do it anyway

    83

    83

    So what about inheritance?

  • 8/8/2019 A Reintroduction to Javascript 4633

    84/111

    Problem: JavaScript is a prototype-basedlanguage, but it pretends to be a class-basedlanguage

    As a result, it doesn't do either very well Inheritance doesn't quite behave how you

    would expect

    84

    84

    Here's a special kind of person

  • 8/8/2019 A Reintroduction to Javascript 4633

    85/111

    p p

    function Geek() {

    Person.apply(this, arguments);this.geekLevel = 5;

    }Geek.prototype = new Person();Geek.prototype.setLevel = function(lvl) {

    this.geekLevel = lvl;}Geek.prototype.getLevel = function() {return this.geekLevel;

    }

    > s = new Geek("Simon", "Willison")> s.fullName()Simon Willison> s.getLevel()

    58585

    new Person()?

  • 8/8/2019 A Reintroduction to Javascript 4633

    86/111

    ()

    We're using an instance of the Person objectas our prototype

    We have to do this, because we need to be

    able to modify our prototype to add newmethods that are only available to Geekinstances

    This is counter-intuitive and, well, a bit dumb

    86

    86

    Solutions?

  • 8/8/2019 A Reintroduction to Javascript 4633

    87/111

    Design classes with inheritance in mind -don't do anything important in the constructor(that might break if you create an emptyinstance for use as a prototype)

    Use one of the many workarounds

    Prototype's Class.create()

    The stuff you get by searching for "javascriptinheritance" on the Web

    87

    87

    http://en.wikipedia.org/wiki/Image:Torres_Petronas_Mayo_2004.jpg ngel Riesgo Martnez

    http://en.wikipedia.org/wiki/Image:Torres_Petronas_Mayo_2004.jpghttp://en.wikipedia.org/wiki/Image:Torres_Petronas_Mayo_2004.jpg
  • 8/8/2019 A Reintroduction to Javascript 4633

    88/111

    88

    Higher order functions

    88

    Functions are first-class objects

  • 8/8/2019 A Reintroduction to Javascript 4633

    89/111

    j

    In English... A function is just another object

    You can store it in a variable

    You can pass it to another function

    You can return it from a function

    89

    89

    VAT

  • 8/8/2019 A Reintroduction to Javascript 4633

    90/111

    VAT is England's national sales tax - 17.5%

    var prices = [10, 8, 9.50];

    var pricesVat = [];

    for (var i = 0; i < prices.length; i++){

    pricesVat[i] = prices[i] * 1.175;

    }

    90

    90

    arrayMap

  • 8/8/2019 A Reintroduction to Javascript 4633

    91/111

    function arrayMap(array, func) {

    var result = [];for (var i = 0; i < array.length; i++) {

    result[i] = func(array[i]);

    }

    return result;

    }

    function calcVat(price) {

    return price * 1.175;

    }

    var prices = [10, 8, 9.50];

    pricesVat = arrayMap(prices, calcVat);

    91

    91

    salesTaxFactory

  • 8/8/2019 A Reintroduction to Javascript 4633

    92/111

    What if we want to calculate sales tax at 4%?

    function salesTaxFactory(percent) {

    function func(price) {

    return price + (percent / 100) * price;

    }

    return func;

    }

    calcVat = salesTaxFactory(17.5);

    calc4 = salesTaxFactory(4);

    pricesVat = arrayMap(prices, calcVat);

    prices4 = arrayMay(prices, calc4);

    92

    92

    An operation factory

  • 8/8/2019 A Reintroduction to Javascript 4633

    93/111

    function makeOp(op, y) {

    switch (op) {case '+':return function(x) { return x + y };

    case '-':return function(x) { return x - y };

    case '/':

    return function(x) { return x / y };case '*':return function(x) { return x * y };

    default:return function(x) { return x };

    }

    }var third = makeOp('/', 3);var dbl = makeOp('*', 2);print(third(24));print(dbl(5));

    93

    93

    Closures

  • 8/8/2019 A Reintroduction to Javascript 4633

    94/111

    The previous code was an example ofclosures in action

    A closure is a function that has captured the

    scope in which it was defined Actually, functions in JavaScript have a

    scope chain (similar to the prototype chain)

    94

    94

    What does this do?

  • 8/8/2019 A Reintroduction to Javascript 4633

    95/111

    95

    function openLinksInNewWindows() {

    for (var i = 0; i < document.links.length; i++) {document.links[i].onclick = function() {

    window.open(document.links[i].href);

    return false;

    }

    }

    }

    The onclick function is a closure which refers back

    to the original scope; it does NOT retain a copy ofthe ivariable at the time the function was created.By the time the onclick function is executed, iwillbe the last value assigned by the loop.

    95

    http://www.flickr.com/photos/iboy_daniel/90450551/ - iboy_daniel / doug wilson

    http://www.flickr.com/photos/iboy_daniel/90450551/http://www.flickr.com/photos/iboy_daniel/90450551/
  • 8/8/2019 A Reintroduction to Javascript 4633

    96/111

    96

    Singleton

    96

    Namespace pollution

  • 8/8/2019 A Reintroduction to Javascript 4633

    97/111

    97

    JavaScript shares a single globalnamespace

    Its easy to clobber other peoples functions

    and variables Its easy for other people to clobber yours

    The less code affecting the global

    namespace the better

    97

    The singleton pattern

  • 8/8/2019 A Reintroduction to Javascript 4633

    98/111

    var simon = (function() {

    var myVar = 5; // Private variablefunction init(x) {// ... can access myVar and doPrivate

    }function doPrivate(x) {// ... invisible to the outside world

    }function doSomething(x, y) {// ... can access myVar and doPrivate

    }return {'init': init, 'doSomething': doSomething

    }})();

    simon.init(x);

    98

    98

    Singleton benefits

  • 8/8/2019 A Reintroduction to Javascript 4633

    99/111

    Singleton lets you wrap up a complexapplication with dozens of functions up in asingle, private namespace - a closure

    This lets you expose only the functions thatmake up your application's external interface

    99

    99

    http://www.flickr.com/photos/lunchtimemama/97685471/ - lunchtimemama / Scott

    http://www.flickr.com/photos/lunchtimemama/97685471/http://www.flickr.com/photos/lunchtimemama/97685471/
  • 8/8/2019 A Reintroduction to Javascript 4633

    100/111

    Memory leaks

    100

    100

    Internet Explorer sucks

  • 8/8/2019 A Reintroduction to Javascript 4633

    101/111

    101

    To understand memory leaks, you have tounderstand a bit about garbage collection

    Stuff gets freed up automatically when it is

    no longer in use (both JavaScript objects andhost objects, such as DOM nodes)

    IE uses different garbage collectors for JS

    and for the DOM, and can't handle circularreferences between them

    101

    This leaks

  • 8/8/2019 A Reintroduction to Javascript 4633

    102/111

    function leak() {

    var div = document.getElementById('d');

    div.obj = {

    'leak': div

    }}

    Call it enough times and IE will crash

    102

    102

    This also leaks

  • 8/8/2019 A Reintroduction to Javascript 4633

    103/111

    function sneakyLeak() {

    var div = document.getElementById('d');

    div.onclick = function() {

    alert("hi!");

    }}

    Why? Spot the closure!

    103

    103

    Difficulties

  • 8/8/2019 A Reintroduction to Javascript 4633

    104/111

    These things can be very hard to detect -especially in large, complex applicationswhere a cycle might occur over many nodesand JavaScript objects

    One solution:function noLeak() {

    var div = document.getElementById('d');

    div.onclick = function() {alert("hi!");

    }

    div = null;

    }

    104

    104

    More solutions

  • 8/8/2019 A Reintroduction to Javascript 4633

    105/111

    Most popular JavaScript libraries havesystems for attaching and detaching events

    Many of these can automatically free event

    references when the page is unloaded Use these, but always be aware of the

    problem

    105

    105

    http://www.flickr.com/photos/javic/100567276/ - javic

    http://www.flickr.com/photos/javic/100567276/http://www.flickr.com/photos/javic/100567276/
  • 8/8/2019 A Reintroduction to Javascript 4633

    106/111

    106

    Performance

    106

    Performance tips

  • 8/8/2019 A Reintroduction to Javascript 4633

    107/111

    107

    De-reference complex lookupsvar s = document.getElementById('d').style;

    s.width = '100%';

    s.color = 'red';

    // ...

    s.display = 'block';

    ... especially inside loops

    var lookup = foo.bar.bav;

    for (var i = 0; i < 1000; i++) {

    lookup.counter += someCalc();

    }

    107

    http://www.flickr.com/photos/klara/94704029/ - klara(!) / klara

    http://www.flickr.com/photos/klara/94704029/http://www.flickr.com/photos/klara/94704029/
  • 8/8/2019 A Reintroduction to Javascript 4633

    108/111

    108

    Libraries

    108

    Suggested libraries

  • 8/8/2019 A Reintroduction to Javascript 4633

    109/111

    109

    dojotoolkit.orgdeveloper.yahoo.net/yui/

    mochikit.com

    prototype.conio.net

    script.aculo.us109

    Tell Alex I told you this...

    http://www.mochikit.com/http://www.mochikit.com/http://www.dojotoolkit.org/http://www.dojotoolkit.org/
  • 8/8/2019 A Reintroduction to Javascript 4633

    110/111

    110

    Everything in JavaScript is an Object. Even

    functions Every object is always mutable

    The dot operator is equivalent to de-referencing by

    hash (e.g., foo.bar === foo["bar"]) The new keyword creates an object that classconstructors run inside of, thereby imprinting them

    Functions are always closures (combine w/ previous

    rule to create OOP) The this keyword is relative to the execution context,

    not the declaration context

    The prototype property is mutable

    110

    http://www.flickr.com/photos/nataliedowne/14517351/ - NatBat / Natalie Downe

    http://www.flickr.com/photos/nataliedowne/14517351/http://www.flickr.com/photos/nataliedowne/14517351/
  • 8/8/2019 A Reintroduction to Javascript 4633

    111/111