我知道结果是 10:
var es = [];
for (var i = 0; i < 10; i++) {
es[i] = function () {
console.log(i);
};
}
es[6]();
任何数量的 es[0] - es[9] 仍然是 10。但是为什么呢?
我知道结果是 10:
var es = [];
for (var i = 0; i < 10; i++) {
es[i] = function () {
console.log(i);
};
}
es[6]();
任何数量的 es[0] - es[9] 仍然是 10。但是为什么呢?
因为在循环之后i
是10
. 该函数打印 的引用i
。
只创建了整数对象。这些console.log(i)
都是指内存中的同一个对象。i
唯一的值i
在循环结束时当然是 10。
请注意,该行console.log(i)
创建了一个闭包,这尤其意味着它没有创建对 . 引用的变量的新引用i
。是同一个参考。
进行此分析的一个好方法是跟踪代码中创建新实际变量的次数。如果您使用 C 或 C++ 或其他语言进行过编程,您就会知道整数占用 4 或 8 个字节的内存。这条线for(var i = 0;
可以被认为是创建一个对象。只有一个。函数内部没有任何东西会创建另一个对象,因为闭包不会这样做。
那是因为当你执行console.log(i)
时,i
循环结束时已经改变了。
更准确地说,当条件为假时,即当is时,for
循环停止。之后你拥有的是 10 个相同的函数,它们都使用相同的外部定义变量。i < 10
i
10
i
你可以使用这个经典的闭包技巧来修复它:
var es = [];
for (var i = 0; i < 10; i++) {
(function(j){
es[j] = function () {
console.log(j);
};
})(i);
}
es[6]();
这段代码所做的是创建一个新变量j
,其作用域是匿名函数调用。这是一种i
在调用函数时保存值的方法(即在循环期间而不是在es[6]
调用时)。
因为您指i
的是循环之后,10
即当您执行console.log(i) 时。i 的值已更改为 10。