javascript - 在 JavaScript 中创建闭包时
问题描述
我想知道在 JavaScript 中创建闭包时
function outerFunc() {
var a = 2;
function() {
console.log(a);
console.log(b);
};
var b = 4;
}
var saveFunc = outerFunc();
saveFunc();
是在执行代码之前创建闭包,还是在调用 outerFunc 时创建闭包,或者在编写 innerFunc 时创建闭包,还是在从 outerFunc 返回 innerFunc 并且将带有闭包的 innerFunc 存储在 saveFunc 中时创建闭包?
解决方案
闭包是在函数定义时创建的。所以,如果你有:
var a = 1;
function foo() {
console.log(a);
}
这是一个关闭。它“关闭”了外部变量。在这种情况下a
。老实说,“关闭”对我来说从来没有意义(可能从不同的角度来看),所以我更喜欢这样想 - 一个可以访问外部范围的函数。在这种情况下a
来自外部范围。
这可能看起来有点奇怪,因为很多关于闭包的例子和解释都有这样的:
function outer() {
var a = 1;
return function inner(b) {//<-----------
return a + b; // |
} // |
} // |
// |
var add1 = outer(); // |
// |
console.log(add1.name); // "inner" ---
console.log(typeof a); // undefined
console.log(add1(41)); // 42
解释是inner
闭包。它在执行后立即创建outer
(定义时间inner
),然后从outer
. 闭包的特殊属性是保留对a
当前超出范围的变量的引用。这是真的,但它给人的印象是错误的。函数中不需要外部引用就可以成为闭包。甚至像这样的纯函数:
function add(a, b) {
return a + b;
}
它不使用外部引用并且完全独立,在创建时形成一个闭包。
简而言之,JavaScript 中的任何函数都是一个闭包,而且从来都不是。
但是,这有点学术性。如前所述,闭包的有用属性是它们保留对它们定义的范围的引用。因此,在实践中,我们通常仅在使用此属性时才引用闭包 - 因此,在示例中,inner
and outer
-都形成了闭包,但我们会关注,inner
因为它实际上使用了外部作用域。