简体   繁体   English

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

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

While working on nodejs programming, I found a simple, but interesting problem. 在进行nodejs编程时,我发现了一个简单但有趣的问题。
To execute a bundle of asynchronous functions in turns, I usually use 'job list array' with async.series. 为了轮流执行一系列异步函数,我通常将ajob.series使用“作业列表数组”。

By following steps : 通过以下步骤:

1. Define an array 1.定义一个数组
2. Push job functions into array. 2.将作业功能推入阵列。
3. Using async.series, execute it sequentially. 3.使用async.series,按顺序执行。
eg async.series(jobFunctionList, callback); 例如async.series(jobFunctionList,callback);

Following example code is simplified one. 以下示例代码已简化。
Described in comment, it doesn't work as I expected. 在评论中进行了描述,但它并不符合我的预期。

The variable 'key' and 'value' changes 变量“键”和“值”发生变化
even after Job function is defined and pushed into jobList array. 即使在定义Job函数并将其推入jobList数组之后。

It seems that pushed function references external variable constantly, 推入函数似乎不断引用外部变量,
not a value of created circumstance. 不是所创造环境的价值。

I found a solution to resolve this problem, but don't know why it works as that. 我找到了解决此问题的解决方案,但不知道为什么会这样工作。

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

*/

As Teemu stated, its because by the time that the for loop finished, the value has already changed 正如Teemu所说,这是因为在for循环结束时,值已经改变了

What you need to do is the following: 您需要执行以下操作:

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])();

Although savedKey and savedValue can be called key and value and it will refer to the new one, which may make more sense reading it 尽管savedKeysavedValue可以称为keyvalue ,它将引用新的keyvalue ,这可能会使savedValue更有意义

The anonymous functions use(share) the same key and value variables from the outer scope. 匿名函数从外部范围使用(共享)相同的键和值变量。 When the for is over, the values they use are key2 value2, not the values they had when the functions were defined. 当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

The solution is to create a closure in which key and value are local: 解决方案是创建一个闭包,其中键和值是本地的:

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