javascript closures for dummies & javascript prototype, closures and oop

16
JavaScript Closures for Dummies by Morris Johns http://blog.morrisjohns.com/javascript_closures_for_dummies

Upload: jin-hwa-kim

Post on 27-May-2015

1.182 views

Category:

Technology


3 download

DESCRIPTION

Summary of Morris Johns' blog article and My practical examples.

TRANSCRIPT

Page 1: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

JavaScript Closures for Dummies by Morris Johns

http://blog.morrisjohns.com/javascript_closures_for_dummies

Page 2: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

scope

Variables have each function scopes.

not in any functions, global variable

Page 3: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

closures

a closure is a stack-frame which is not dealloctated when the funtion returns. (as if a 'stack-frame' were malloc'ed instead of being on the stack!)

In JavaScript, if you use the function keyword inside another function, you are creating a closure.

as soon as there are no more references to the function that is using the closure, the function/closures should be garbage collected.

Page 4: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

comparative

C pointer

- a pointer to a function

JavaScript reference

- a pointer to a function & a hidden pointer to a closure

Page 5: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

example 3function say667(){

// Local variable that ends up within closurevar num = 666;var sayAlert = function() { alert(num); }num++;return sayAlert;

}

This example shows that the local variables are not copied - they are kept by reference. It is kind of like keeping a stack-frame in memory when the outer function exits

Page 6: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

example 4function setupSomeGlobals(){

 // Local variable that ends up within closure var num = 666; // Store some references to functions as global variables gAlertNumber = function() { alert(num); } gIncreaseNumber = function() { num++; } gSetNumber = function(x) { num = x; }

}

All three global functions have a common reference to the same closure because they are all declared within a single call to setupSomeGlobals().

Page 7: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

JavaScript prototype, closures and OOP

by Jin Hwa Kim

Page 8: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

McDuck

Duck

overview

Bird

Page 9: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

var Bird = function() { // constructor var kind = "bird"; this.setKind = function(k){ kind = k; }; this.getKind = function(){ return kind; }; this.fly = function(){ console.log( kind + " do fly." ); }; this.sing = function(){ console.log( "lalala." ); };}var angrybird = new Bird();

console.log( angrybird.kind ); // undefinedconsole.log( angrybird.getKind() ); // birdangrybird.fly(); // bird do fly.angrybird.sing(); // lalala.

Page 10: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

inheritance

In prototype-based programming, objects can be defined directly from other objects without the need to define any classes, in which case this feature is called differential inheritance.

Differential Inheritance is a common inheritance model used by prototype-based programming languages such as JavaScript, Io and NewtonScript. It operates on the principle that most objects are derived from other, more general objects, and only differ in a few small aspects; while usually maintaining a list of pointers internally to other objects which the object differs from.

from wikipedia

Page 11: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

// Definition of constructorvar Duck = function() { var kind = "duck"; this.shape = "beige feathered duck"; this.describe = function(){ console.log( this.shape ) }; // Overriding, surely. this.fly = function(){ console.log( kind + " can't fly." ); };};Duck.prototype = Bird; // not workedDuck.prototype = new Bird();

var dornald = new Duck();dornald.describe(); // beige feathered duckdornald.fly(); // duck can't fly.dornald.sing(); // lalala.

Page 12: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

var McDuck = function() { var kind = "McDuck"; var steal = function(){ console.log( "steal the money." ); }; this.shape = "white feathered duck"; this.tax = function(){ steal(); console.log( "pay the tax." ); };};McDuck.prototype = new Duck();

var scrooge = new McDuck();console.log( scrooge.shape ); // white feathered duckconsole.log( scrooge.kind ); // undefinedconsole.log( scrooge.getKind() ); // birdconsole.log( typeof scrooge.steal ); // undefinedscrooge.describe(); // white feathered duckscrooge.tax(); // steal the money.\n pay the tax.

Page 13: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

// Polymorphismvar birds = [ angrybird, dornald, scrooge ];for( var i in birds ){ birds[i].fly(); // bird do fly.\n duck can't fly.\n duck can't fly.}

Page 14: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

var sum = 0;function add_t() { var sum = sum + 20; }add_t();alert( ++sum );

Page 15: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

use case 1Prototype's bind() function or Dojo's dojo.lang.hitch() function use closures.

Inside the function the this keyword becomes a reference to that scope. The same function can behave differently depending on its execution scopre.

Prototype can guarantee that your function will execute with the object you want under the this keyword just by invoking bind on it.

from Prototype JavaScript framework: Function.bind (http://www.prototypejs.org/api/function/bind)

Page 16: JavaScript Closures for Dummies & JavaScript prototype, closures and OOP

use case 2LCMCalculator.prototype = { ... gcd: function () { var a = Math.abs(this.a), b = Math.abs(this.b), t; if (a < b) { t = b; b = a; a = t; } while (b !== 0) { t = b; b = a % b; a = t; } this['gcd'] = function() { return a; }; return a; } ... };

Only need to calculate GCD once, so "redefine" this method. (Actually not redefinition - it's defined on the instance itself, so that this.gcd refers to this "redefinition" instead of LCMCalculator.prototype.gcd.)

from wikipedia