执行上下文和闭包
Execution context and closures
我知道如何实现闭包,但我很难理解为什么会发生闭包。例如:
function foo(){
var a = 4;
return function innerFoo(){
alert(a);
};
};
var bar = foo();
bar(); // alerts 4
当我看到上面的代码时,我知道会发生什么,但是当我尝试从逻辑上遵循它时,它没有意义。我认为我对执行上下文及其范围链的理解是错误的。
这就是我希望程序运行的方式:
function foo(){
var a = 4;
return function innerFoo(){
alert(a);
};
};
var bar = foo(); // function foo() is executed, creating a foo execution context(EC)
// fooEC = {scopeChain: [fooEV.VO, globalEC.VO],
// VO: {innerFoo: pointer to innerFoo(),
// a: 4}};
// So, the pointer to innerFoo() is returned to bar
// fooEC is exited
bar(); // bar points to code in innerFoo(), creates a innerFoo execution context
// innerFooEC = {scopeChain: [innerFoo.VO, globalEC.VO],
// VO: { }};
// interpreter searches innerFooEC.VO for variable "a", none found, looks
// down the scope chain at the global variable object,
// globalEC = {scopeChain: [globalEC.VO],
// VO: {foo: pointer to foo(),
// bar: pointer to innerFoo()}};
// a is undefined
我哪里做错了?
错误在
bar points to code in innerFoo()
闭包不仅仅是一个指向代码的指针,它是一个指向代码的指针和一个环境;这是定义a
的环境。
作用域链是定义闭包时处于活动状态的链(即在foo
内部),而不是进行调用的链。
请注意,闭包捕获变量,而不是值。这可以观察到:
function getset(x) {
var a = x;
function getter() { return a; }
function setter(x) { a = x; }
return [getter, setter];
}
var gs1 = getset(12);
var gs2 = getset(34);
console.log(gs1[0]()); // --> 12
console.log(gs2[0]()); // --> 34
gs1[1](1122);
gs2[1](3344);
console.log(gs1[0]()); // --> 1122
console.log(gs2[0]()); // --> 3344
即每对 getter/setter 将在两个闭包之间共享自己的变量,但与另一对分开。
这是我的经验中循环中创建闭包最常见的错误的根源:
for (var i=0; i<10; i++) {
var node = document.createElement("div");
node.textContent = "click me (" + i + ")";
node.onclick = function() { alert(i); };
document.body.appendChild(node);
}
在此代码中,单击所有 10 个元素时将显示相同的数字 (10),因为所有闭包都共享循环中使用的相同i
变量,而 10 是变量将具有的最终值。
相关文章:
- 在underscorejs模板中使用闭包
- setTimeout可以与闭包内的函数一起使用吗
- 附加到原型属性的Do函数没有闭包
- 使用闭包共享构造函数参数
- 使用Google闭包编译器包含一个Ecmascript 6类
- 从js引擎的角度来看闭包和构造函数是如何工作的
- for循环中的JavaScript闭包
- Javascript闭包-如何防止内存泄漏
- 如何设置javascript闭包的上下文
- 执行上下文和闭包
- python中的闭包.我可以在函数的本地上下文上关闭吗?
- jQuery移动触摸事件处理,此关键字上下文,并正确使用闭包
- 对循环中的上下文使用javascript闭包
- jQuery事件处理程序闭包与上下文
- JavaScript闭包上下文的其他属性发生了什么
- 回调函数、闭包和执行上下文
- JS闭包和执行上下文的创建
- 在JavaScript中调用闭包时,是在输入闭包代码时创建的新执行上下文
- Javascript闭包和执行上下文-评估代码的问题
- 美元.每个都在模块闭包中更改此上下文