Skip to content

Instantly share code, notes, and snippets.

@wangzuo
Created October 20, 2012 14:48
Show Gist options
  • Save wangzuo/3923470 to your computer and use it in GitHub Desktop.
Save wangzuo/3923470 to your computer and use it in GitHub Desktop.
javascript closure
// Define a function that sets a DOM node's color
// to yellow and then fades it to white.
var fade = function (node) {
var level = 1;
var step = function () {
var hex = level.toString(16); node.style.backgroundColor = '#FFFF' + hex + hex; if (level < 15) {
level += 1;
setTimeout(step, 100);
}
};
setTimeout(step, 100);
};
fade(document.body);
// BAD EXAMPLE
// Make a function that assigns event handler functions to an array of nodes the wrong way. // When you click on a node, an alert box is supposed to display the ordinal of the node. // But it always displays the number of nodes instead.
var add_the_handlers = function (nodes) {
var i;
for (i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = function (e) {
alert(i);
};
}
};
// END BAD EXAMPLE
// BETTER EXAMPLE
// Make a function that assigns event handler functions to an array of nodes.
// When you click on a node, an alert box will display the ordinal of the node.
var add_the_handlers = function (nodes) {
var helper = function (i) { // binds the current value of i
return function (e) {
alert(i);
};
};
var i;
for (i = 0; i < nodes.length; i += 1) {
nodes[i].onclick = helper(i);
}
};
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}
var sayAlert = say667();
sayAlert(); // 667
function 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; }
}
setupSomeGlobals();
gAlertNumber(); // 666
gIncreaseNumber();
gAlertNumber(); // 667
gSetNumber(12);
gAlertNumber(); // 12
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(function() { alert(item + ' ' + list[i]) });
}
return result;
}
function testList() {
var fnlist = buildList([1,2,3]);
// using j only to help prevent confusion - could use i
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}
testList(); // "item3 undefined" alert for 3 times
function sayAlice() {
var sayAlert = function() { alert(alice); }
// Local variable that ends up within closure
var alice = 'Hello Alice';
return sayAlert;
}
var helloAlice = sayAlice();
helloAlice(); // "Hello Alice"
function newClosure(someNum, someRef) {
// Local variables that end up within closure
var num = someNum;
var anArray = [1,2,3];
var ref = someRef;
return function(x) {
num += x;
anArray.push(num);
alert('num: ' + num +
'\nanArray ' + anArray.toString() +
'\nref.someVar ' + ref.someVar);
}
}
// 2 different closures
closure1 = newClosure(40, {someVar:'closure 1'});
closure2 = newClosure(1000, {someVar:'closure 2'});
closure1(5); // num:45 anArray[1,2,3,45] ref:'someVar closure1'
closure2(-10); // num:990 anArray[1,2,3,990] ref:'someVar closure2'
var singleton = function () {
var privateVariable;
function privateFunction(x) {
...privateVariable...
}
return {
firstMethod: function (a, b) {
...privateVariable...
},
secondMethod: function (c) {
...privateFunction()...
}
};
}();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment