我已阅读以下针对How do JavaScript Closures work?
的答案发布的示例7的代码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);
}
}
obj = {someVar: 4};
fn1 = newClosure(4, obj);
fn2 = newClosure(5, obj);
fn1(1); // num: 5; anArray: 1,2,3,5; ref.someVar: 4;
fn2(1); // num: 6; anArray: 1,2,3,6; ref.someVar: 4;
obj.someVar++;
fn1(2); // num: 7; anArray: 1,2,3,5,7; ref.someVar: 5;
fn2(2); // num: 8; anArray: 1,2,3,6,8; ref.someVar: 5;
我为我的例子使用了相同的逻辑
function increment() {
var id = 0;
return function(number) {
id += number;
alert('Unique ID: ' + id);
}
}
six = increment();
fourteen = increment();
six(6);
fourteen(8);
在我从中获取灵感的例子中,
fn1(2); //num 7
num输出7因为根据我的理解,它从第一次调用前设置为5。所以使用相同的推理,我期望十四(8)次调用返回数字14,因为我相信ID会更新为6而不是保持为0.为什么变量不是静态的?我如何将其视为静态?
我还尝试让函数设置一个数字参数,并将ID设置为等于参数,但也没有更新它。
答案 0 :(得分:2)
newClosure
的关闭会在每次调用时捕获num
初始化为someNum
。因此,f1
有自己的num
,从4
开始,递增1到5
,然后递增2到7
。同时,f2
有自己的num
,从5
开始,加1到6
,再加2到8
。 f1
和f2
调用的交错可能会让您感到困惑,但它们完全是分开的,并且不会共享任何变量。
同样,increment
构造的闭包将捕获id
值0
。 six
从id
开始0
,递增6到6
。 fourteen
独立地从自己的0
开始,并以8增加到8
。
比较
var globalCounter = 0;
function incrementWithGlobalCounter() {
var counter = 0;
return function(number) {
counter += number;
globalCounter += number;
alert('Counter: ' + counter + '; Global Counter: ' + globalCounter);
}
}
var one = incrementWithGlobalCounter();
var two = incrementWithGlobalCounter();
one(1); // 1, 1
one(1); // 2, 2
two(1); // 1, 3
two(2); // 3, 5
one(5); // 7, 10
这里,globalCounter
被外部闭包捕获,因此它被所有内部闭包共享; counter
由内部闭合和局部到外部闭合捕获,因此每个内部闭合都是独立的。