繁体   English   中英

JavaScript关闭-将匿名函数的奇怪引用功能推到数组

[英]JavaScript Closure - Strange reference feature of anonymous function pushed to Array

在进行nodejs编程时,我发现了一个简单但有趣的问题。
为了轮流执行一系列异步函数,我通常将ajob.series使用“作业列表数组”。

通过以下步骤:

1.定义一个数组
2.将作业功能推入阵列。
3.使用async.series,按顺序执行。
例如async.series(jobFunctionList,callback);

以下示例代码已简化。
在评论中进行了描述,但它并不符合我的预期。

变量“键”和“值”发生变化
即使在定义Job函数并将其推入jobList数组之后。

推入函数似乎不断引用外部变量,
不是所创造环境的价值。

我找到了解决此问题的解决方案,但不知道为什么会这样工作。

var dataList = { key1: 'value1', key2: 'value2' };

var jobList = new Array();

for (var key in dataList)
{
    var value = dataList[key];

    jobList.push(
        function (next)
        {
            console.log(key + ' : ' + value);
        }
    );
}

(jobList[0])();
(jobList[1])();

/* Expected Output :

key1 : value1
key2 : value2

*/

/* Real Output :

key2 : value2  <--- WHY ???
key2 : value2

*/

正如Teemu所说,这是因为在for循环结束时,值已经改变了

您需要执行以下操作:

var dataList = { key1: 'value1', key2: 'value2' };

var jobList = new Array();

for (var key in dataList)
{
    var value = dataList[key];

    jobList.push(
        (function(savedKey, savedValue) {
            return function (next) {
                console.log(savedKey + ' : ' + savedValue);
            }
        })(key, value)
    );
}

(jobList[0])();
(jobList[1])();

尽管savedKeysavedValue可以称为keyvalue ,它将引用新的keyvalue ,这可能会使savedValue更有意义

匿名函数从外部范围使用(共享)相同的键和值变量。 当for结束时,它们使用的值是key2 value2,而不是定义函数时使用的值。

for (var key in dataList) // definition of key
{
    var value = dataList[key]; // definition of value

    jobList.push(
        function (next)
        {
            console.log(key + ' : ' + value); // uses key and value from the outer scope
        }
    );
}

(jobList[0])(); // key and value are key2 value2 after for, so they are printed
(jobList[1])(); // same

解决方案是创建一个闭包,其中键和值是本地的:

for (var key in dataList) // definition of key
{
    var value = dataList[key]; // definition of value

    jobList.push(
      function(k,v){ // k,v local copies of key and value
        return function (next)
          {
            console.log(k + ' : ' + v); // uses local copies, created one for each iteration
          }
      }(key,value); // immediately execute the outer anonymous function, it just creates a local scope
    );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM