我知道结果是 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 < 10i10i
你可以使用这个经典的闭包技巧来修复它:
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。