簡體   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