我对for循环中声明的函数的关闭行为非常困惑,特别是对初始化程序中定义的变量:
function createFunctions(){
const functions = []
for(let i = 0; i < 5; i++)
functions.push(() => i);
return functions;
}
const results = createFunctions().map(m => m())
// results: [0, 1, 2, 3, 4]vs
function createFunctions(){
const functions = []
let i;
for(i = 0; i < 5; i++)
functions.push(() => i);
return functions;
}
const results = createFunctions().map(m => m())
// results: [5, 5, 5, 5, 5]因为在for循环中声明的匿名箭头函数捕获了它的作用域,所以我认为这两种情况都会产生[5, 5, 5, 5, 5],因为在调用时,i的值是5。然而,第一个结果似乎表明,在每次循环迭代时,i都是一个不同的变量。但是,如果重复测试,但初始化的变量是对象而不是数字:
function createFunctions(){
const functions = []
for(let obj = {}, i = 0; i < 5; i++)
functions.push(() => obj);
return functions;
}
const results = createFunctions().map(m => m())
// results: [{}, {}, {}, {}, {}]; results[0] === results[1]: true我们可以看到,返回的数组中的所有元素在引用上都是相等的,因此变量也不是不同的。因此,函数关闭在for循环初始化器中声明的变量的方式似乎会根据变量是否是原语而改变,这在我看来很荒谬。
我遗漏了什么?
发布于 2020-04-22 01:21:52
所以,我费了很大劲才写出这个问题,在研究的过程中,我偶然找到了答案,所以我想我应该把这个问题转换成一个自我回答的问题,这样如果其他人遇到同样的行为,可能会更容易找到。
我找到了答案here
在循环中,如果让-声明一个变量,那么每次迭代都会得到一个新的绑定。允许您这样做的循环有:
for、for-in和for-of。
这就解释了为什么两个对象是相等的:我们得到一个新的变量,这个变量在循环结束时赋给前一个变量的值。在对象的情况下,新变量指向相同的对象,这解释了引用相等。它还解释了为什么第一种情况会产生[0, 1, 2, 3, 4]:与对象不同,数字是值,而不是引用。
https://stackoverflow.com/questions/61349374
复制相似问题