![Page 1: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/1.jpg)
Advanced JavaScript:Advanced JavaScript:closures, prototypes, closures, prototypes, inheritanceinheritance
Stoyan StefanovAjax Experience, Boston 2008
![Page 2: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/2.jpg)
About the presenter
• Yahoo! performance
team member
• YSlow 2.0 architect, dev
• Book author, open-source
contributor
• Blog: http://phpied.com
![Page 3: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/3.jpg)
Before we start… Firebug console
![Page 4: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/4.jpg)
Firebug console is a learning tool
![Page 5: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/5.jpg)
Firebug console…
• Inspect the contents of objects by clicking on
them
• Tab auto-complete, a.k.a cheatsheet
• Arrows ↑ and↓
• Fiddle with any page
![Page 6: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/6.jpg)
Any page…
![Page 7: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/7.jpg)
Fiddle…
![Page 8: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/8.jpg)
Objects
![Page 9: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/9.jpg)
JavaScript data types
primitive and objects
• number
• string
• boolean
• undefined
• null
![Page 10: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/10.jpg)
What’s an object?
• a hash of key => value pairs
• if a key (property) happens to be a function,
we can call it a method
![Page 11: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/11.jpg)
What’s an object?
var obj = {
shiny: true,
isShiny: function() {
return this.shiny;
}
};
obj.isShiny(); // true
![Page 12: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/12.jpg)
Object literal notation
• { Wrapped in curly braces }
• ,-delimited properties
• key:value pairs
var obj = {a: 1, "b c d": 2};
![Page 13: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/13.jpg)
Arrays
![Page 14: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/14.jpg)
Arrays
• arrays are also objects
• auto-incremented properties
![Page 15: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/15.jpg)
Arrays
>>> var a = [1,3,2];
>>> a[0]
1
>>> typeof a
"object"
![Page 16: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/16.jpg)
Arrays
• array objects also get some cool properties...
>>> a.length
3
• ...and methods
>>> a.sort()
>>> a.join(' < ')
"1 < 2 < 3"
![Page 17: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/17.jpg)
Array literal notation
var array = [
"Square", "brackets",
"wrap", "the",
"comma-delimited",
"elements"
];
![Page 18: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/18.jpg)
JSON
• JavaScript Object Notation
• Uses object and array literals
• Quotes required for properties
{"num": 1, "str": "abc", "arr": [1,2,3]}
![Page 19: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/19.jpg)
Functions
![Page 20: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/20.jpg)
Functions
• functions are objects
• they have properties
• they have methods
• can de copied, deleted, augmented...
• special feature: invokable
![Page 21: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/21.jpg)
Functions
function boo(what) {
return what;
}
• or
var boo = function(what) {
return what;
};
![Page 22: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/22.jpg)
Functions
function boo(what) {
return what;
}
• or
var boo = function bootoo(what) {
return what;
};
![Page 23: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/23.jpg)
Functions are objects
>>> boo.length
1
>>> boo.name
"bootoo"
![Page 24: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/24.jpg)
Functions are objects
>>> var foo = boo;
>>> foo("doodles")
"doodles"
>>> foo.call(null, "moo!");
"moo!"
![Page 25: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/25.jpg)
Return value
• all functions return a value
• if they don't explicitly, they return
undefined implicitly
• functions can return other functions
![Page 26: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/26.jpg)
Constructors
![Page 27: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/27.jpg)
Constructors
• when invoked with new, functions return an
object known as this
• you have a chance of modifying this before
it's returned
• you can also return some other object
![Page 28: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/28.jpg)
Constructor functions
var Person = function(name) {
this.name = name;
this.speaks = 'fr';
this.say = function() {
return "Je m'appelle " + this.name;
};
};
![Page 29: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/29.jpg)
An object created with constructor
>>> var julien = new Person("Julien");
>>> julien.say();
"Je m'appelle Julien"
![Page 30: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/30.jpg)
Constructor’s return value
var Person = function(){
this.first = "Bruce";
return {last: "Wayne"};
};
>>> typeof new Person().first
"undefined"
>>> new Person().last
"Wayne"
![Page 31: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/31.jpg)
Constructor’s return value
var Person = function(){
this.first = "Bruce";
return "Batman";
};
>>> new Person().first
"Bruce"
![Page 32: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/32.jpg)
Naming convention
• MyConstructor
• myFunction
![Page 33: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/33.jpg)
constructor property
>>> function Person(){};
>>> var jo = new Person();
>>> jo.constructor === Person
true
![Page 34: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/34.jpg)
constructor property
>>> var o = {};
>>> o.constructor === Object
true
>>> [1,2].constructor === Array
true
![Page 35: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/35.jpg)
Built-in constructor functions
• Object
• Array
• Function
• RegExp
• Number
• String
• Boolean
• Date
• Error, SyntaxError, ReferenceError…
![Page 36: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/36.jpg)
Use this Not that
var o = {}; var o = new Object();
var a = []; var a = new Array();
var re = /[a-z]/gmi; var re = new RegExp(
'[a-z]', 'gmi');
var fn = function(a, b){
return a + b;
}
var fn = new Function(
'a, b','return a+b');
![Page 37: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/37.jpg)
Wrapper objects vs. primitive
>>> typeof new Number(1)
"object"
>>> typeof 1
"number"
![Page 38: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/38.jpg)
Primitives can act as objects
>>> "test".length
4
>>> (123.456).toFixed(2)
"123.46"
![Page 39: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/39.jpg)
Prototype
![Page 40: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/40.jpg)
prototype
• a property of the function objects
>>> var boo = function(){};
>>> typeof boo.prototype
"object"
![Page 41: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/41.jpg)
Prototypes can be augmented
>>> boo.prototype.a = 1;
>>> boo.prototype.sayAh = function(){};
![Page 42: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/42.jpg)
Prototypes can be overwritten
>>> boo.prototype = {a: 1, b: 2};
![Page 43: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/43.jpg)
How is the prototype used?
• when a function is invoked as a constructor
var Person = function(name) {
this.name = name;
};
Person.prototype.say = function() {
return this.name;
}
![Page 44: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/44.jpg)
>>> var dude = new Person('dude');
>>> dude.name;
"dude"
>>> dude.say();
"dude"
How is the prototype used?
![Page 45: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/45.jpg)
• say() is a property of the prototype
object
• but it behaves as if it's a property of the dude
object
• can we tell the difference?
How is the prototype used?
![Page 46: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/46.jpg)
Own properties vs. prototype’s
>>> dude.hasOwnProperty('name');
true
>>> dude.hasOwnProperty('say');
false
![Page 47: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/47.jpg)
isPrototypeOf()
>>> Person.prototype.isPrototypeOf(dude);
true
>>> Object.prototype.isPrototypeOf(dude);
true
![Page 48: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/48.jpg)
__proto__
• I, the dude, have a secret link to the
prototype of the constructor that created me
• __proto__ is not directly exposed in all
browsers
![Page 49: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/49.jpg)
>>> dude.__proto__.hasOwnProperty('say')
true
>>> dude.prototype
??? // Trick question
>>> dude.__proto__.__proto__.hasOwnProperty('toString')
true
__proto__
![Page 50: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/50.jpg)
The prototype chain
![Page 51: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/51.jpg)
It’s alive!
>>> typeof dude.numlegs
"undefined"
>>> Person.prototype.numlegs = 2;
>>> dude.numlegs
2
![Page 52: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/52.jpg)
Inheritance
![Page 53: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/53.jpg)
Inheritance via the prototype
>>> var Dad = function(){this.family = "Stefanov";};
>>> var Kid = function(){};
>>> Kid.prototype = new Dad();
>>> var billy = new Kid();
>>> billy.family
"Stefanov"
![Page 54: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/54.jpg)
Inherit one more time
>>> var GrandKid = function(){};
>>> GrandKid.prototype = billy;
>>> var jill = new GrandKid();
>>> jill.family
"Stefanov"
![Page 55: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/55.jpg)
Inheritance…
>>> jill.hasOwnProperty('family')
false
>>> jill.__proto__.hasOwnProperty('family')
false
>>> jill.__proto__.__proto__.hasOwnProperty('family')
true
![Page 56: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/56.jpg)
Inheritance…
>>> billy.family = 'Idol';
>>> jill.family;
'Idol'
>>> jill.__proto__.hasOwnProperty('family');
true
>>> delete billy.family;
>>> jill.family;
'Stefanov'
![Page 57: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/57.jpg)
Side effect…
>>> billy.constructor === Kid
false
>>> billy.constructor === Dad
true
![Page 58: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/58.jpg)
Side effect… easy to solve
• reset after inheritance
>>> Kid.prototype.constructor = Kid;
>>> GrandKid.prototype.constructor =
GrandKid;
![Page 59: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/59.jpg)
isPrototypeOf
>>> billy.isPrototypeOf(jill)
true
>>> Kid.prototype.isPrototypeOf(jill)
true
![Page 60: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/60.jpg)
instanceof
>>> jill instanceof GrandKid
true
>>> jill instanceof Kid
true
>>> jill instanceof Dad
true
![Page 61: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/61.jpg)
Classes?
• There are no classes in JavaScript
• Objects inherit from objects
• classical inheritance is when we think of
constructors as if they were classes
![Page 62: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/62.jpg)
Classical inheritance
function Parent(){this.name = 'parent';}
Parent.prototype.getName = function(){
return this.name;
};
function Child(){}
inherit(Child, Parent);
![Page 63: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/63.jpg)
Option 1
function inherit(C, P) {
C.prototype = new P();
}
![Page 64: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/64.jpg)
Option 2
function inherit(C, P) {
C.prototype = P.prototype;
}
![Page 65: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/65.jpg)
Option 3
function inherit(C, P) {
var F = function(){};
F.prototype = P.prototype;
C.prototype = new F();
}
![Page 66: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/66.jpg)
Option 3 + super
function inherit(C, P) {
var F = function(){};
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype;
}
![Page 67: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/67.jpg)
Option 3 + super + constructor reset
function inherit(C, P) {
var F = function(){};
F.prototype = P.prototype;
C.prototype = new F();
C.uber = P.prototype; // super
C.prototype.constructor = C; // reset
}
![Page 68: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/68.jpg)
Inheritance by copying properties
• After all, inheritance is all about code reuse
function extend(parent) {
var i, child = {};
for (i in parent) {
child[i] = parent[i];
}
return child;
}
![Page 69: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/69.jpg)
Inheritance by copying…
>>> var parent = {a: 1};
>>> var child = extend(parent);
>>> child.a
1
![Page 70: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/70.jpg)
Inheritance by copying…
• This was a shallow copy
• you can make a deep copy using recursion
• mixins / multiple inheritance
![Page 71: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/71.jpg)
Prototypal inheritance
• as suggested by Douglas Crockford
• no class-like constructors involved
• objects inherit from objects
• via the prototype
![Page 72: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/72.jpg)
Prototypal inheritance
function object(o) {
function F(){}
F.prototype = o;
return new F();
}
![Page 73: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/73.jpg)
Prototypal inheritance
>>> var parent = {a: 1};
>>> var child = object(parent);
>>> child.a;
1
>>> child.hasOwnProperty(a);
false
![Page 74: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/74.jpg)
Scope
![Page 75: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/75.jpg)
No block scope
>>> if (true) {var inside_block = 1;}
>>> inside_block
1
![Page 76: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/76.jpg)
Function scope
function boo() {
var inboo = true;
}
![Page 77: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/77.jpg)
Global namespace
• every variable is global unless it's in a
function and is declared with var
• global namespace should be kept clean to
avoid naming collisions
• function scope can help
![Page 78: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/78.jpg)
Self-executable functions for one-off tasks
(function(){
var a = 1;
var b = 2;
alert(a + b);
})()
![Page 79: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/79.jpg)
Closures
![Page 81: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/81.jpg)
![Page 82: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/82.jpg)
Closure example #1
function outer(){
var local = 1;
return function(){
return local;
};
}
![Page 83: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/83.jpg)
example #1…
>>> var inner = outer()
>>> inner()
1
![Page 84: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/84.jpg)
Closure example #2
var inner;
function outer(){
var local = 1;
inner = function(){
return local;
};
}
![Page 85: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/85.jpg)
example #2…
>>> typeof inner
"undefined"
>>> outer()
>>> inner()
1
![Page 86: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/86.jpg)
Closure example #3
function makePlus(arg) {
var n = function(){
return arg;
};
arg++;
return n;
}
![Page 87: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/87.jpg)
example #3…
>>> var getValue = makePlus(1234);
>>> getValue()
1235
![Page 88: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/88.jpg)
Closure #4 – in a loop
function make() {
var i, a = [];
for(i = 0; i < 3; i++) {
a[i] = function(){
return i;
}
}
return a;
}
![Page 89: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/89.jpg)
Closure #4 test - oops
>>> var funcs = make();
>>> funcs[0]();
3
>>> funcs[1]();
3
>>> funcs[2]();
3
![Page 90: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/90.jpg)
Closure #4 – corrected
function make() {
var i, a = [];
for(i = 0; i < 3; i++) {
a[i] = (function(local){
return function(){return local;}
})(i)
}
return a;
}
![Page 91: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/91.jpg)
Getter/Setter
var getValue, setValue;
(function() {
var secret = 0;
getValue = function(){
return secret;
};
setValue = function(v){
secret = v;
};
})()
// usage>>> getValue()0>>> setValue(123)>>> getValue()123
![Page 92: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/92.jpg)
Iterator
function setup(x) {
var i = 0;
return function(){
return x[i++];
};
}
![Page 93: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/93.jpg)
Iterator usage
>>> var next = setup(['a', 'b', 'c']);
>>> next()
'a'
>>> next()
'b'
![Page 94: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/94.jpg)
Loop through DOM elements - wrong
// all elements will alert 5
for (var i = 1; i < 5; i++ ){
document.getElementById('btn'+i).onclick =
function(){
alert(i);
};
}
![Page 95: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/95.jpg)
Loop through DOM elements - correct
// first element alerts 1, second 2,...
for (var i = 1; i < 5; i++ ){
document.getElementById('btn'+i).onclick =
(function(i){
return function(){alert(i);};
})(i)
}
![Page 96: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/96.jpg)
Wrapping up…
• How to tell what’s going on?
typeof, instanceof, isPrototypeOf()…
![Page 97: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/97.jpg)
>>> typeof variable
• typeof is an operator, not a function
• Not typeof(variable) even if it works
• Returns a string, one of:
"string", "number", "boolean",
"undefined", "object", "function"
![Page 98: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/98.jpg)
typeof
if (typeof whatever === "undefined") {
// whatever is not defined
}
if (whatever == undefined) {
// hmm, not so sure
}
![Page 99: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/99.jpg)
>>> obj instanceof MyConstructor
• Not instanceof()
• Returns true | false
• true for all constructors up the chain
![Page 100: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/100.jpg)
>>> obj.constructor
• Points to the constructor function used to
create this obj
![Page 101: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/101.jpg)
>>> obj.isPrototypeOf(child_obj)
• Respects the prototype chain
![Page 102: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/102.jpg)
>>> obj.hasOwnProperty("prop")
• Own properties vs. properties of the
prototype
![Page 103: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/103.jpg)
obj.propertyIsEnumerable("prop")
• Will it show up in a for-in loop
• Caution: enumerable properties of the
prototype will return false but still show up
in the for-in loop
![Page 104: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/104.jpg)
Wrapping up…
• What did we learn today?
![Page 105: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/105.jpg)
Objects
• JavaScript has a few primitive types,
everything else is an object
• Objects are hashes
• Arrays are objects
![Page 106: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/106.jpg)
Functions
• Functions are objects, only invokable
• call() and apply() methods
• prototype property
![Page 107: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/107.jpg)
Prototype
• Functions have a prototype property which is
an object
• Useful with Constructor functions
![Page 108: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/108.jpg)
Constructor
• A function meant to be called with new
• Returns an object
![Page 109: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/109.jpg)
Class
• No such thing in JavaScript
![Page 110: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/110.jpg)
Inheritance
• Prototypal
• Classical
• … and approximately 101 other ways and
variations
![Page 111: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/111.jpg)
Scope
• Lexical function scope
![Page 112: Advanced JavaScript: Closures, Prototypes and Inheritance](https://reader033.vdocuments.us/reader033/viewer/2022061220/54bc87624a795966278b45ee/html5/thumbnails/112.jpg)
Closure
• When a variable leaves its function scope