【问题标题】:For loop initializer capture [duplicate]For循环初始化程序捕获[重复]
【发布时间】:2020-08-04 13:03:35
【问题描述】:

我对在 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]

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。然而,第一个结果似乎表明在每次迭代中通过循环,我是一个不同的变量。但是,如果您重复测试但初始化的变量是对象而不是数字:

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 循环初始化程序中声明的变量的方式会根据变量是否为原始变量而改变,这对我来说听起来很荒谬。

我错过了什么?

【问题讨论】:

    标签: javascript functional-programming closures


    【解决方案1】:

    所以,我在写这个问题时遇到了所有的麻烦,在研究过程中我偶然发现了答案,所以我想我会把它改成一个自我回答的问题,这样如果其他人遇到同样的行为,可能更容易找到。

    我找到了答案here

    在循环中,每次迭代都会获得一个新的绑定,如果你 let-声明一个变量。允许您这样做的循环是:forfor-infor-of

    这解释了为什么对象是相等的:我们得到一个新变量,它在循环结束时被分配给前一个变量的值。在对象的情况下,新变量指向同一个对象,这解释了引用相等性。它还解释了为什么第一种情况会产生[0, 1, 2, 3, 4]:与对象不同,数字是值,而不是引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 2013-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多