在javascript中绕过变量提升回调

Zeo*_*ite 0 javascript

我对Javascript的理解是变量具有函数作用域而不是块作用域,因此在块内声明的变量将被提升到它上面的函数.该文章给出了下面的代码示例:

var arr = [1, 2, 3, 4]  
for(var i = 0; i < arr.length; i++) { 
  var entry = arr[i];
  setTimeout(function() {
    console.log(entry);
  }, 100);
}
Run Code Online (Sandbox Code Playgroud)

文章声明代码被转换为以下内容,因此变量entry在每次迭代之间是通用的.结果是4四次登录到控制台

var arr, i, len, entry;
arr = [1, 2, 3, 4]  
for(i = 0; i < arr.length; i++) {  
  entry = arr[i];
  setTimeout(function() {
    console.log(entry);
  }, 100);
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我希望每次调用setTimeout都记录不同的值,我应该如何重写代码arr

jca*_*ron 6

您可以将更setTimeout改为:

setTimeout(
   (function()
      {
          var entry = arr[i];
          return function() {console.log(entry);}
      }
   )()
);
Run Code Online (Sandbox Code Playgroud)

这样,您创建了一个新范围,并且entry在该范围内.

你也可以这样做:

(function(e)
    {
        setTimeout(function(){console.log(e);});
    }
)(entry);
Run Code Online (Sandbox Code Playgroud)

这也创造了一个新的范围,其中的e谎言.

还有一个选择:

setTimeout(
    (function(e)
        {
            return function() {console.log(e);};
        }
    )(entry);
);
Run Code Online (Sandbox Code Playgroud)

在所有情况下,您使用您立即调用的匿名函数,因此唯一的副作用是您正在创建新范围.

(编辑:重新格式化了一点以便于阅读,并添加了更多解释)