https://developer.mozilla.org...
closure is the combination of a function and the lexical environment within which that function was declared.
闭包是一个函数和其内部公开变量的环境的集合.
简单而言, 闭包 = 函数 + 环境闭包
function init() { var name = 'Mozilla'; // name is a local variable created by init function displayName() { // displayName() is the inner function, a closure alert(name); // use variable declared in the parent function } displayName(); } init(); because inner functions have access to the variables of outer functions, displayName() can access the variable name declared in the parent function, init().
var data = [ {'key':0}, {'key':1}, {'key':2} ]; function showKey() { for(var i=0;i<data.length;i++) { setTimeout(function(){ //console.log(i); //发现i输出了3次3 //console.log(this); // 发现 this 指向的是 Window data[i].key = data[i].key + 10; console.log(data[i].key) }, 1000); } } showKey();
上面这个例子能够正确输出 10 11 12 吗?
答案是:并不能,而且还会报语法错误....函数
因此须要再定义一个执行函数this
var data = [ {'key':0}, {'key':1}, {'key':2} ]; function showKey() { var f1 = function(n){ data[i].key = data[i].key + 10; console.log(data[i].key) } for(var i=0;i<data.length;i++) { setTimeout(f1(i), 1000); } } showKey(); // 获得预期的 10 11 12
function makeAdder(x) { return function(y) { return function(z) { return x + y + z; } }; } console.log(makeAdder(1)(2)(3)); // 6 // function factory it creates functions which can add a specific value to their argument var add5 = makeAdder(5); console.log(add5(1)(2)); // 8 console.log(add5(4)(5)); // 14
var counter = (function() { // private variable var privateCounter = 0; // private function function changeBy(val) { privateCounter += val; } return { changeValue: function(val) { changeBy(val); }, value: function() { return privateCounter; } }; })(); console.log(counter.value()); // logs 0 // 实现了内部属性的获取 counter.changeValue(2);// 实现了内部的changeBy()方法 counter.changeValue(10); console.log(counter.value()); // logs 12 counter.changeValue(-5); console.log(counter.value()); // logs 7
var makeCounter = function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } } }; var counter1 = makeCounter(); var counter2 = makeCounter(); alert(counter1.value()); /* Alerts 0 */ counter1.increment(); counter1.increment(); alert(counter1.value()); /* Alerts 2 */ counter1.decrement(); alert(counter1.value()); /* Alerts 1 */ alert(counter2.value()); /* Alerts 0 */