java scriptpatterns
DESCRIPTION
Un design pattern è soluzione generale e riusabile ad un problema ricorrente; ma tutti i design patterns "classici" possono essere utilizzati in Javascript? Esistono design patterns tipici di Javascript? In questo talk vedremo quali design pattern classici si possono implementare in Javascript, e come, così come nuovi pattern possono sfruttare al massimo le caratteristiche del linguaggio.TRANSCRIPT
![Page 1: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/1.jpg)
Giordano Scalzo
JavaScript Patterns
Wednesday, November 10, 2010
![Page 2: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/2.jpg)
I’m not a guru!
Wednesday, November 10, 2010
![Page 3: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/3.jpg)
I’m still learning
Wednesday, November 10, 2010
![Page 4: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/4.jpg)
Why?
Wednesday, November 10, 2010
![Page 5: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/5.jpg)
JavaScript isn’t this anymore
Wednesday, November 10, 2010
![Page 6: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/6.jpg)
JavaScript is everywhere!
Wednesday, November 10, 2010
![Page 7: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/7.jpg)
Technology Radar
JavaScript is trendy!
Wednesday, November 10, 2010
![Page 8: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/8.jpg)
Technology Radar
JavaScript is trendy!
Wednesday, November 10, 2010
![Page 9: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/9.jpg)
At the beginning...
Wednesday, November 10, 2010
![Page 10: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/10.jpg)
Hacked by Brendan Eich in one week...
Wednesday, November 10, 2010
![Page 11: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/11.jpg)
Former Mocha, renamed to JavaScript by Netscape
Wednesday, November 10, 2010
![Page 12: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/12.jpg)
after a while...
Wednesday, November 10, 2010
![Page 13: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/13.jpg)
and...
Wednesday, November 10, 2010
![Page 14: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/14.jpg)
:-(
Wednesday, November 10, 2010
![Page 15: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/15.jpg)
and so...
Wednesday, November 10, 2010
![Page 16: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/16.jpg)
Back to study!
Wednesday, November 10, 2010
![Page 17: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/17.jpg)
Started a notebook...
Wednesday, November 10, 2010
![Page 18: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/18.jpg)
Essential
Scope
Wednesday, November 10, 2010
![Page 19: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/19.jpg)
function sum(x, y){ // implied global result = x + y; return result;}
{antipattern}Wednesday, November 10, 2010
![Page 20: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/20.jpg)
Global variables are evil!
Wednesday, November 10, 2010
![Page 21: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/21.jpg)
Variables clash
Wednesday, November 10, 2010
![Page 22: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/22.jpg)
Always declare variables with var
function sum(x, y){ var result = x + y; return result;}
{pattern}Wednesday, November 10, 2010
![Page 23: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/23.jpg)
function foo(){ var a = b = 0; //...}
{antipattern}Wednesday, November 10, 2010
![Page 24: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/24.jpg)
function foo(){ var a = (b = 0); //...}
{antipattern}
b become global
Wednesday, November 10, 2010
![Page 25: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/25.jpg)
function foo(){ var a, b; a = b = 0; //...}
don’t use assign chain in definition
{pattern}Wednesday, November 10, 2010
![Page 26: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/26.jpg)
function func(){ var a = 1,
b = 2, sum = a + b, myobject = {}, i, j;
// function body...}
{pattern}
Single var pattern
Wednesday, November 10, 2010
![Page 27: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/27.jpg)
Don’t forget comma otherwise...
Wednesday, November 10, 2010
![Page 28: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/28.jpg)
... variables become globals
Wednesday, November 10, 2010
![Page 29: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/29.jpg)
Hoisting
myname = "global"; // global variable function func(){ // code... console.log(myname); // "undefined"
// code... var myname = "local"; console.log(myname); // "local"}
func();
{antipattern}Wednesday, November 10, 2010
![Page 30: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/30.jpg)
Hoisting
myname = "global"; // global variable function func(){ var myname = "declared"; // code... console.log(myname); // "declared"
// code... myname = "local"; console.log(myname); // "local"}
func();
{pattern}Wednesday, November 10, 2010
![Page 31: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/31.jpg)
“Variables should be declared as close to their usage as possible”
Robert C. Martin - Clean Code
Against minimum vertical distance principle
Wednesday, November 10, 2010
![Page 32: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/32.jpg)
EssentialLiteral and Constructor
Wednesday, November 10, 2010
![Page 33: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/33.jpg)
In JavaScript almost everything is an object
Wednesday, November 10, 2010
![Page 34: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/34.jpg)
var person = new Object();person.name = "Scott";person.say = function(){ return "I am " + this.name;};
console.log(person.say());
It’s easy...
Wednesday, November 10, 2010
![Page 35: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/35.jpg)
var person = new Object();person.name = "Scott";person.say = function(){ return "I am " + this.name;};
console.log(person.say());
{antipattern}
but wrong! :-(
Wednesday, November 10, 2010
![Page 36: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/36.jpg)
var person = {};person.name = "Scott";person.say = function(){ return "I am " + this.name;};
console.log(person.say());
{pattern}Wednesday, November 10, 2010
![Page 37: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/37.jpg)
What if we need similar objects...
var person = {};person.name = "Scott";person.say = function(){ return "I am " + this.name;};console.log(person.say()); // I am Scott
var otherPerson = {};otherPerson.name = "Tiger";otherPerson.say = function(){ return "I am " + this.name;};
console.log(otherPerson.say()); // I am Tiger
Wednesday, November 10, 2010
![Page 38: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/38.jpg)
A lot of duplication
var person = {};person.name = "Scott";person.say = function(){ return "I am " + this.name;};console.log(person.say()); // I am Scott
var otherPerson = {};otherPerson.name = "Tiger";otherPerson.say = function(){ return "I am " + this.name;};
console.log(otherPerson.say()); // I am Tiger
Wednesday, November 10, 2010
![Page 39: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/39.jpg)
Duplication is evil!
Wednesday, November 10, 2010
![Page 40: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/40.jpg)
var Person = function(name){ this.name = name; this.say = function(){ return "I am " + this.name; }}var person = new Person("Scott");
console.log(person.say()); // I am Scott
Custom Constructor Functions
{pattern}Wednesday, November 10, 2010
![Page 41: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/41.jpg)
Behind the scenes...
var Person = function(name){ // var this = {}; this.name = name; this.say = function(){ return "I am " + this.name; }; // return this;};
{pattern}Wednesday, November 10, 2010
![Page 42: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/42.jpg)
var Person = function(name){ this.name = name; this.say = function(){ return "I am " + this.name; };};
var scott = new Person('Scott');var tiger = new Person('Tiger');
console.log(scott.say());console.log(tiger.say());
So, at the end...
{pattern}Wednesday, November 10, 2010
![Page 43: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/43.jpg)
What if we forget new?
Wednesday, November 10, 2010
![Page 44: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/44.jpg)
var Person = function(name){ this.name = name; this.say = function(){ return "I am " + this.name; };};
var scott = new Person('Scott')var adam = Person('Adam')
console.log(typeof scott); //objectconsole.log(scott.name); // Scottconsole.log(typeof adam); //'undefined'console.log(window.name); // Adam
this will point to global object
Wednesday, November 10, 2010
![Page 45: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/45.jpg)
Enforce new pattern one: naming convention
Wednesday, November 10, 2010
![Page 46: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/46.jpg)
var Person = function(name){ var that = {}; that.name = name; that.say = function(){ return "I am " + that.name;}; return that;};
var scott = new Person('Scott')var adam = Person('Adam')
console.log(typeof scott); //Objectconsole.log(scott.name); // Scott
console.log(typeof adam); //Objectconsole.log(adam.name); // Adam
{pattern}Wednesday, November 10, 2010
![Page 47: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/47.jpg)
Drawback: we loose prototype reference :-(
var Person = function(name){ var that = {}; that.name = name; that.say = function(){ return "I am " + that.name; }; return that;};
Person.prototype.iamhumanbeing = true;
var scott = new Person('Scott')var adam = Person('Adam')
console.log(scott.iamhumanbeing); // undefinedconsole.log(adam.iamhumanbeing); // undefined
Wednesday, November 10, 2010
![Page 48: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/48.jpg)
Interm!zoPrototype property
Wednesday, November 10, 2010
![Page 49: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/49.jpg)
Define ancestors chain
var foo = {one: 1, two: 2};var bar = {three: 3};foo.__proto__ = bar;console.log(foo.one);console.log(foo.three);
Wednesday, November 10, 2010
![Page 50: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/50.jpg)
foo
one: 1
__proto__
bar
three: 3
two: 2
Wednesday, November 10, 2010
![Page 51: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/51.jpg)
var Person = function(name){ // this.prototype = {constructor: this} var that = {}; that.name = name; that.say = function(){ return "I am " + that.name; }; return that;};
Behind the scenes...
Wednesday, November 10, 2010
![Page 52: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/52.jpg)
var Person = function(name){ if (this instanceof Person) { this.name = name; this.say = function(){ return "I am " + that.name; } } else { return new Person(name); }};Person.prototype.iamhumanbeing = true;var scott = new Person('Scott')var adam = Person('Adam')console.log(scott.name); // Scottconsole.log(adam.name); // Adamconsole.log(scott.iamhumanbeing); // trueconsole.log(adam.iamhumanbeing); // true
Self invoking constructor
{pattern}Wednesday, November 10, 2010
![Page 53: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/53.jpg)
EssentialFunctions
Wednesday, November 10, 2010
![Page 54: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/54.jpg)
Functions as first class objects
Wednesday, November 10, 2010
![Page 55: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/55.jpg)
Immediate functions
(function(){ alert('watch out!');})();
Wednesday, November 10, 2010
![Page 56: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/56.jpg)
Initialization pattern
(function(){ var days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], today = new Date(), msg = 'Today is ' + days[today.getDay()] + ', ' + today.getDate(); console.log(msg);})(); // "Today is Wed, 10"
{pattern}Wednesday, November 10, 2010
![Page 57: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/57.jpg)
Function scope
Wednesday, November 10, 2010
![Page 58: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/58.jpg)
// constructors function Parent(){}
function Child(){}
// a variablevar some_var = 1;// some objects var module1 = {};module1.data = { a: 1, b: 2};var module2 = {};
{antipattern}
5 globals...
Wednesday, November 10, 2010
![Page 59: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/59.jpg)
// global object var MYAPP = (function(){ var my = {}; // constructors my.Parent = function(){}; my.Child = function(){}; // a variable my.some_var = 1; // an object container my.modules = {}; // nested objects my.modules.module1 = {}; my.modules.module1.data = { a: 1, b: 2 }; my.modules.module2 = {}; return my;})();
console.log(MYAPP.modules.module1.data.a); // 1
{pattern}1 global!
Wednesday, November 10, 2010
![Page 60: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/60.jpg)
What about encapsulation?
Wednesday, November 10, 2010
![Page 61: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/61.jpg)
function Gadget(){ this.name = 'iPod'; this.stretch = function(){ return 'iPad'; }};
var toy = new Gadget();console.log(toy.name); // `iPod` toy.name = 'Zune'console.log(toy.name); // `Zune` is public console.log(toy.stretch()); // stretch() is public
{antipattern}Wednesday, November 10, 2010
![Page 62: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/62.jpg)
function Gadget(){ var name = 'iPod'; this.getName = function(){ return name; }};
var toy = new Gadget();console.log(toy.getName()); // `iPod`toy.name = 'Zune'console.log(toy.getName()); // `iPod`
Create private member
{pattern}Wednesday, November 10, 2010
![Page 63: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/63.jpg)
function Gadget() { var name = 'iPod'; var upgrade = function(){ return 'iPhone'; }
this.getName = function () { return name; } this.pay = function() { return upgrade(); }};
var toy = new Gadget(); console.log(toy.pay()); // `iPhone`console.log(toy.upgrade()); // `error`
{pattern}
for methods too
Wednesday, November 10, 2010
![Page 64: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/64.jpg)
AdvancedCode reuse patterns
Wednesday, November 10, 2010
![Page 65: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/65.jpg)
vs
Classical vs prototypal inheritance
Wednesday, November 10, 2010
![Page 66: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/66.jpg)
Classical inheritancefunction Parent(name){ this.name = name;};
Parent.prototype.say = function(){ return 'My name is ' + this.name;};
function Child(name){ this.name = name;};
inherit(Child, Parent);
var dad = new Parent('Larry');var kid = new Child('Scott');
console.log(dad.say()); // 'My name is Larry'console.log(kid.say()); // 'My name is Scott'
Wednesday, November 10, 2010
![Page 67: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/67.jpg)
new Parent()
name: Larry__proto__
Parent.prototypesay()
console.log(dad.say());
function(){ return 'My name is ' + this.name;};
Wednesday, November 10, 2010
![Page 68: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/68.jpg)
Default Classical Inheritance pattern
function inherit(C, P) { C.prototype = new P();};
Wednesday, November 10, 2010
![Page 69: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/69.jpg)
new Parent()
name: Larry__proto__
Parent.prototypesay()
new Child()
name: Scott__proto__
console.log(kid.say());
function(){ return 'My name is ' + this.name;};
Wednesday, November 10, 2010
![Page 70: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/70.jpg)
function Parent(name){ this.name = name;};
Parent.prototype.say = function(){ return 'My name is ' + this.name;};
function Child(name){ this.name = name;};
inherit(Child, Parent);
var dad = new Parent('Larry');var kid = new Child('Scott');
console.log(dad.say()); // 'My name is Larry'console.log(kid.say()); // 'My name is Scott'
Drawback: it doesn’t call parent constructor
Wednesday, November 10, 2010
![Page 71: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/71.jpg)
function Parent(name){ this.name = name;};
Parent.prototype.say = function(){ return 'My name is ' + this.name;};
function Child(name){ };
function inherit(C, P) { C.prototype = new P();};
inherit(Child, Parent);
var kid = new Child('Scott');
console.log(kid.say()); // 'My name is undefined'
Drawback: it doesn’t call parent constructor
Wednesday, November 10, 2010
![Page 72: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/72.jpg)
function Child(name){ Parent.apply(this, arguments); };
Pattern Extension: rent a constructor
Wednesday, November 10, 2010
![Page 73: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/73.jpg)
function Parent(name){ this.name = name;};Parent.prototype.say = function(){ return 'My name is ' + this.name;};
function Child(name){ Parent.apply(this, arguments);};
function inherit(C, P){ C.prototype = new P();};inherit(Child, Parent);var dad = new Parent('Larry');var kid = new Child('Scott');console.log(dad.say()); // 'My name is Larry'console.log(kid.say()); // 'My name is Scott'
Pattern Extension: rent a constructor
Wednesday, November 10, 2010
![Page 74: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/74.jpg)
function Parent(name){ this.name = name;};Parent.prototype.say = function(){ return 'My name is ' + this.name;};
function Child(name){ Parent.apply(this, arguments);};
function inherit(C, P){ C.prototype = new P();};inherit(Child, Parent);var dad = new Parent('Larry');var kid = new Child('Scott');console.log(dad.say()); // 'My name is Larry'console.log(kid.say()); // 'My name is Scott'
Drawback: parent constructor is called twice
Wednesday, November 10, 2010
![Page 75: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/75.jpg)
function Parent(name){ this.name = name;};Parent.prototype.say = function(){ return 'My name is ' + this.name;};
function Child(name){ Parent.apply(this, arguments);};
function inherit(C, P){ C.prototype = new P();};inherit(Child, Parent);var dad = new Parent('Larry');var kid = new Child('Scott');console.log(dad.say()); // 'My name is Larry'console.log(kid.say()); // 'My name is Scott'
Drawback: parent constructor is called twice
Wednesday, November 10, 2010
![Page 76: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/76.jpg)
function Parent(name){ this.name = name;};Parent.prototype.say = function(){ return 'My name is ' + this.name;};
function Child(name){ Parent.apply(this, arguments);};
function inherit(C, P){ C.prototype = new P();};inherit(Child, Parent);var dad = new Parent('Larry');var kid = new Child('Scott');console.log(dad.say()); // 'My name is Larry'console.log(kid.say()); // 'My name is Scott'
Drawback: parent constructor is called twice
Wednesday, November 10, 2010
![Page 77: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/77.jpg)
mmmm let’s try with the same prototype
Wednesday, November 10, 2010
![Page 78: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/78.jpg)
function inherit(C, P){ C.prototype = P.prototype;};
Share the same prototype
Wednesday, November 10, 2010
![Page 79: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/79.jpg)
new Parent()
name: Larry__proto__
Parent.prototypesay()
new Child()
name: Scott__proto__
Wednesday, November 10, 2010
![Page 80: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/80.jpg)
Share the same prototype
Inheritance works as expectedConstructor called only onceLow memory footprint
Wednesday, November 10, 2010
![Page 81: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/81.jpg)
Share the same prototype
Child objects can affect other objects
Wednesday, November 10, 2010
![Page 82: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/82.jpg)
function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F();};
Enhance the pattern: temporary constructor
Wednesday, November 10, 2010
![Page 83: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/83.jpg)
new Parent()
name: Larry__proto__
Parent.prototypesay()
new Child()
name: Scott__proto__
new F()
__proto__
Wednesday, November 10, 2010
![Page 84: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/84.jpg)
function inherit(C, P) { var F = function () {}; F.prototype = P.prototype; C.prototype = new F(); C.uber = P.prototype; C.prototype.constructor = C;};
The Holy Grail Pattern of classical inheritance
Wednesday, November 10, 2010
![Page 85: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/85.jpg)
We got it!
Wednesday, November 10, 2010
![Page 86: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/86.jpg)
What about Prototypal Inheritance?
Wednesday, November 10, 2010
![Page 87: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/87.jpg)
No more classes, only objects
Wednesday, November 10, 2010
![Page 88: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/88.jpg)
var parent = { name: "Larry", say: function(){ return "My name is " + this.name; }};
var child = object(parent);child.name = 'Scott'
console.log(child.say()); // "Scott"
What we want in prototypal inheritance
Wednesday, November 10, 2010
![Page 89: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/89.jpg)
function object(o) { function F() {} F.prototype = o; return new F();};
Prototypal inheritance function
Wednesday, November 10, 2010
![Page 90: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/90.jpg)
child = new F()
name: Larry__proto__
parent
name: Scottsay()
Wednesday, November 10, 2010
![Page 91: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/91.jpg)
With constructor function
var Parent = function(name){ this.name = name; this.say = function(){ return "My name is " + this.name; }};
var child = object(new Parent("Larry"));child.name = 'Scott'
console.log(child.say()); // "Scott"
Wednesday, November 10, 2010
![Page 92: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/92.jpg)
better classical or prototypal?
Wednesday, November 10, 2010
![Page 93: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/93.jpg)
It depends
Wednesday, November 10, 2010
![Page 94: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/94.jpg)
Goals of inheritance is reuse and reduce duplication
Wednesday, November 10, 2010
![Page 95: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/95.jpg)
isA relationship...Liskov principle...
difficult to tame inheritance...
Wednesday, November 10, 2010
![Page 96: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/96.jpg)
A modern and better approach is to use
Mix-In
Wednesday, November 10, 2010
![Page 97: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/97.jpg)
var Serializer = function () {};Serializer.prototype = { serialize: function () { var output = []; for (key in this) { // append this[key] to output // ... } return output.join(', '); }};
A beahviour...
Wednesday, November 10, 2010
![Page 98: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/98.jpg)
var XmlBuilder = function () {};XmlBuilder.prototype = { toXml: function () { var output = ''; for (key in this) { // append xml of this[key] to output // ... } return output; }};
another beahviour...
Wednesday, November 10, 2010
![Page 99: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/99.jpg)
var Author = function (name, books) { this.name = name || ""; this.books = books || [];}
and an object...
Wednesday, November 10, 2010
![Page 100: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/100.jpg)
augment(Author, Serializer);augment(Author, XmlBuilder);
var author = new Author('Umberto Eco', ['Il nome della rosa', 'Il Pendolo di Foucault']);var serializedString = author.serialize();console.log(serializedString); // name: Umberto Eco, // books: Il nome della rosa,
// Il Pendolo di Foucaultvar xmlString = author.toXml();console.log(xmlString); //<name>Umberto Eco</name> // <book>Il nome della rosa</book> // <book>Il Pendolo di Focault</book>
result!
Wednesday, November 10, 2010
![Page 101: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/101.jpg)
function augment(receivingClass, givingClass) { for (methodName in givingClass.prototype) { if (!receivingClass.prototype[methodName]) { receivingClass.prototype[methodName] =
givingClass.prototype[methodName]; } }}
The recipe
Wednesday, November 10, 2010
![Page 102: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/102.jpg)
AdvancedDesign Patterns
Wednesday, November 10, 2010
![Page 103: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/103.jpg)
Wednesday, November 10, 2010
![Page 104: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/104.jpg)
“A design pattern is a general reusable solution to a commonly occurring problem”
Wednesday, November 10, 2010
![Page 105: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/105.jpg)
JavaScript is not J@#*!
Wednesday, November 10, 2010
![Page 106: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/106.jpg)
creation of objectssubclasses decide which class to instantiate
Factory pattern
Wednesday, November 10, 2010
![Page 107: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/107.jpg)
var BicycleFactory = { createBicycle: function(model){ var bicycle; switch (model) { case 'The Speedster': bicycle = new Speedster(); break; case 'The Lowrider': bicycle = new Lowrider(); break; case 'The Comfort Cruiser': default: bicycle = new ComfortCruiser(); } Interface.ensureImplements(bicycle, Bicycle); bicycle.assemble(); bicycle.wash(); return bicycle; }};var californiaCruisers = new BicycleFactory();var yourNewBike = californiaCruisers.createBicycle('The Speedster');
Wednesday, November 10, 2010
![Page 108: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/108.jpg)
var XMLHttpFactory = function(){ this.createXMLHttp = function(){ if (typeof XMLHttpRequest !== "undefined") { return XMLHttpRequest(); } else if (typeof window.ActiveXObject !== "undefined") { return ActiveXObject("MSXML2.XMLHttp"); } else { alert("XHR Object not in production"); } }};
var xhr = new XMLHttpFactory().createXMLHttp();
A more concrete example...
Wednesday, November 10, 2010
![Page 109: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/109.jpg)
It seems lightly broken....
Wednesday, November 10, 2010
![Page 110: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/110.jpg)
var XMLHttpFactory = function(){ this.createXMLHttp = function(){ if (typeof XMLHttpRequest !== "undefined") { return XMLHttpRequest(); } else if (typeof window.ActiveXObject !== "undefined") { return ActiveXObject("MSXML2.XMLHttp"); } else { alert("XHR Object not in production"); } }};
var xhr = new XMLHttpFactory().createXMLHttp();
Wednesday, November 10, 2010
![Page 111: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/111.jpg)
Chain of Responsibility pattern
Wednesday, November 10, 2010
![Page 112: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/112.jpg)
var XhrStandard = function(){ this.canHandle = function(){ return typeof XMLHttpRequest !== "undefined"; }
this.xhr = function(){ return XMLHttpRequest(); } };
Extract condition and action....
Wednesday, November 10, 2010
![Page 113: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/113.jpg)
var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ return ActiveXObject("MSXML2.XMLHttp"); } };
another condition and action....
Wednesday, November 10, 2010
![Page 114: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/114.jpg)
var XhrError = function(){ this.canHandle = function(){ return true; } this.xhr = function(){ throw("XHR Object not in production"); } };
and last one condition and action....
Wednesday, November 10, 2010
![Page 115: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/115.jpg)
var XMLHttpFactory = function(){ //... ChainLinks...
var creators = [new XhrStandard(), new XhrIe(), new XhrError()];
this.createXMLHttp = function(){ var creator; for(var i = 0; i < creators.length; ++i){ creator = creators[i]; if(creator.canHandle()) { return creator.xhr(); } } }};
var xhr = new XMLHttpFactory().createXMLHttp();console.log(xhr);
and the engine!
Wednesday, November 10, 2010
![Page 116: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/116.jpg)
Or following the book...
Wednesday, November 10, 2010
![Page 117: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/117.jpg)
var XhrStandard = function(){ this.canHandle = function(){ return typeof XMLHttpRequest !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return XMLHttpRequest(); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } };
Refactored an action...
Wednesday, November 10, 2010
![Page 118: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/118.jpg)
var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return ActiveXObject("MSXML2.XMLHttp"); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } };
other action...
Wednesday, November 10, 2010
![Page 119: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/119.jpg)
var XhrError = function(){ this.canHandle = function(){ return true; } this.xhr = function(){ throw ("XHR Object not in production"); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } };
last action...
Wednesday, November 10, 2010
![Page 120: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/120.jpg)
var XMLHttpFactory = function(){ //... ChainLinks... var creator = (function(){ var head = new XhrIe(); head.addSuccessor(new XhrStandard()) .addSuccessor(new XhrError()); return head; })(); this.createXMLHttp = function(){ return creator.xhr(); }};
var xhr = new XMLHttpFactory().createXMLHttp();console.log(xhr);
and the engine!
Wednesday, November 10, 2010
![Page 121: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/121.jpg)
mmm duplication...
Wednesday, November 10, 2010
![Page 122: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/122.jpg)
var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return ActiveXObject("MSXML2.XMLHttp"); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } };
Same for all...
Wednesday, November 10, 2010
![Page 123: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/123.jpg)
var XhrIe = function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.xhr = function(){ if (this.canHandle()) { return ActiveXObject("MSXML2.XMLHttp"); } return this.successor.xhr(); } this.addSuccessor = function(successor){ this.successor = successor; return this.successor; } };
Similar for all..
Wednesday, November 10, 2010
![Page 124: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/124.jpg)
Template Method pattern
Wednesday, November 10, 2010
![Page 125: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/125.jpg)
... and a little bit of Mix-In
Template Method pattern
Wednesday, November 10, 2010
![Page 126: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/126.jpg)
var ChainLink = function() {}; ChainLink.prototype.exec = function(){ if(this.canHandle()) { return this.doIt(); } return this.successor.exec(); };
ChainLink.prototype.addSuccessor = function(successor){ this.successor = successor; return this.successor; }
Extracted same and similar behaviours....
Wednesday, November 10, 2010
![Page 127: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/127.jpg)
var XhrStandard = augment(function(){ this.canHandle = function(){ return typeof XMLHttpRequest !== "undefined"; } this.doIt = function(){ return XMLHttpRequest(); }; }, ChainLink);
Augment an action...
Wednesday, November 10, 2010
![Page 128: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/128.jpg)
var XhrIe = augment(function(){ this.canHandle = function(){ return typeof ActiveXObject !== "undefined"; } this.doIt = function(){ return this.doIt(); }; }, ChainLink);
another action...
Wednesday, November 10, 2010
![Page 129: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/129.jpg)
var XhrError = augment(function(){ this.canHandle = function(){ return true; }
this.doIt = function(){ throw("XHR Object not in production"); } },ChainLink);
and last one.
Wednesday, November 10, 2010
![Page 130: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/130.jpg)
var XMLHttpFactory = function(){ //... ChainLinks... var creator = (function(){ var head = new XhrIe(); head.addSuccessor(new XhrStandard()) .addSuccessor(new XhrError()); return head; })(); this.createXMLHttp = function(){ return creator.xhr(); }};
var xhr = new XMLHttpFactory().createXMLHttp();console.log(xhr);
and the engine is the same!
Wednesday, November 10, 2010
![Page 131: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/131.jpg)
It’s just a beginning...
Wednesday, November 10, 2010
![Page 132: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/132.jpg)
peep codepeep code
Wednesday, November 10, 2010
![Page 133: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/133.jpg)
Study
Wednesday, November 10, 2010
![Page 134: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/134.jpg)
Wednesday, November 10, 2010
![Page 135: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/135.jpg)
Wednesday, November 10, 2010
![Page 136: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/136.jpg)
“Save it for a rainy day!”
Wednesday, November 10, 2010
![Page 137: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/137.jpg)
Check your code with jslint.com
Wednesday, November 10, 2010
![Page 138: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/138.jpg)
Wednesday, November 10, 2010
![Page 139: Java scriptpatterns](https://reader035.vdocuments.us/reader035/viewer/2022070316/555c2293d8b42a09438b4a51/html5/thumbnails/139.jpg)
@giordanoscalzo
www.slideshare.net/giordano
github.com/gscalzo
Wednesday, November 10, 2010