javascript - 需要帮助理解 JS 代码

标签 javascript closures

<分区>

您好,我是 javascript 的新手,我无法理解以下代码:

var createAdders = function () {

    var fns = [];

    for (var i = 1; i < 4; i++) {

        fns[i] = (function (n) {
            return i + n;
        });
    }
    return fns;
}
var adders = createAdders();
adders[1](7); //11 ??
adders[2](7); //11 ??
adders[3](7); //11 ??

据我所知,7 被作为参数传递,但是 createAdders() 没有将 7 分配给任何变量,所以这是否意味着 7 被传递给 中的下一个函数createAdders() 即匿名函数并分配给变量 n

我的逻辑正确吗?

上面的代码似乎确实有效,但每次调用的结果都是 11。 我在一个非常可靠的博客中找到了这段代码,作为闭包有用的情况的示例。然后按以下方式更改上面的代码以引用闭包的优点。

var createAdders = function () {
    var fns = [];
    for (var i = 1; i < 4; i++) {
        (function (i) {
            fns[i] = (function (n) {
                return i + n;
            });
        })(i)     //// why is (i) used here? what purpose does it serve??////
    }
    return fns;
}

var adders = createAdders();
adders[1](7); //8 
adders[2](7); //9 
adders[3](7); //10

同样的逻辑也适用于此吗?

我需要了解 n 是如何被赋予值 7

为什么 (i) 在新代码的函数末尾使用?

最佳答案

在 JavaScript 中,我们没有 block 作用域,只有函数作用域。

在第一个例子中,唯一的i声明属于createAdders作用域,表示在 for 中创建的所有函数循环将在范围链中查找相同的 i并返回相同的值。用代码解释:

//   here's the only `i` declaration
for (var i = 1; i < 4; i++) {

    fns[i] = (function (n) {
        return i + n; //this line will retrieve the `i` variable declared above,
                      //that being always 4 after the loop ends
    });
}

在第二个示例中,您正在创建一个带有 IIFE 的新范围在循环内部 - 它为每次迭代创建一个新的执行上下文。

在 IIFE 内部创建的函数将访问 IIFE 的执行上下文的 i .这i当您传递外部 i 时,每次迭代都是唯一的到 IIFE,成为 IIFE 的形式参数 i .

简而言之,每次迭代都会创建一个新的执行上下文,它有自己的 i通过 IIFE 包装器。

按顺序阅读评论:

//  1. Outer `i` declared here
for (var i = 1; i < 4; i++) {
    (function (i) {// 3. Outer `i` becomes the formal parameter `i` of the IIFE, 
                   // it is a "different" `i` in a new execution context (scope)
        fns[i] = (function (n) {
            return i + n; // 4. seeks the `i` value of the IIFE
        });
    })(i) // 2. Outer `i` passed to IIFE
}

当您调用在 IIFE 内部创建的函数时,作用域链将检索“最近的”i在范围链中,这是形式参数 i在其中创建函数的 IIFE。

关于javascript - 需要帮助理解 JS 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13458889/

相关文章:

javascript - 在文档范围内按键后调用组件函数 (React)

javascript - 通过多个页面的 FireBreath 插件

ios - 这个闭包怎么写?

javascript - 嵌套 for 循环始终显示最后的数据

javascript - 你可以在不使用 NodeJS 的情况下使用 npm 包吗

javascript - Canvas 游戏开发和性能

javascript - 在 nodejs 上启动新进程

php - 在闭包函数参数PHP中添加类-引发未捕获的TypeError

将 Ada 闭包转换为 C 回调(函数 + void*)

javascript - 为什么不能在闭包的私有(private)函数中直接访问 this 的属性?