【问题标题】:Workaround for let keyword?let 关键字的解决方法?
【发布时间】:2011-03-08 00:09:43
【问题描述】:

我怎样才能得到这个

var i = 0;
var codes = [1, 2, 3];

for (var i = 0; i < codes.length; ++i)
{
    setTimeout(function(){alert(codes[i]);},100);
}

alert123不使用let关键字?

或在元素上绑定事件 (example):

var i = 0;
var codes = [1, 2, 3];

for (var i = 0; i < codes.length; ++i)
{
    $("div").eq(i).click(function(){
        alert( codes[i] );
    });
}

【问题讨论】:

    标签: javascript let


    【解决方案1】:

    使用自执行匿名函数并传入i 作为变量闭包的参数。

    var i = 0;
    var codes = [1, 2, 3];
    
    for (var i = 0; i < codes.length; ++i)
    {
        (function( index ) {
            setTimeout(function(){alert(codes[index]);},100);
        })(i);
    }
    

    Here's an example.

    【讨论】:

    • 这会导致所有 3 个同时关闭,这是所需的功能吗?
    • 如果没有,他可以把setTimeout上的延迟改成100*(index+1)
    【解决方案2】:

    您需要使用闭包。我通常创建一个“生成器”函数,该函数返回一个在所需上下文中定义的函数:

    var i = 0;
    var codes = [1, 2, 3];
    function callbackGenerator(i) { 
       return function(){alert(codes[i]);}
    }
    
    for (var i = 0; i < codes.length; ++i)
    {
        setTimeout(callbackGenerator(i), 100);
    }
    

    更多信息和很好的例子在这里: https://developer.mozilla.org/en/JavaScript/Guide/Closures

    【讨论】:

      【解决方案3】:
      var i = 0;
      var codes = [1, 2, 3];
      
      var timeoutFunc = function() {
          alert(codes[i++]);
          if (i < codes.length) {
              setTimeout(timeoutFunc, 100);
          }
      };
      
      setTimeout(timeoutFunc, 100);
      

      【讨论】:

        【解决方案4】:

        应该这样做。

        var codes = [1, 2, 3];
        
        for (var i = 0; i < codes.length; ++i)
            setTimeout(function(code){return function(){
                alert(code);
            }}(codes[i]), 100);
        

        【讨论】:

          【解决方案5】:

          使用self-executing function

          for (var i = 0; i < codes.length; ++i) (function(bound_i) {
              setTimeout(function(){alert(codes[bound_i]);},100);
          })(i);
          

          可选地使用var 语句以获得更详细的代码:

          for (var i = 0; i < codes.length; ++i) (function() {
              var bound_i = i;
              setTimeout(function(){alert(codes[bound_i]);},100);
          })();
          

          如果您愿意,也可以使用命名函数:

          function foo(i) {
              setTimeout(function(){alert(codes[i]);},100);
          }
          
          for (var i = 0; i < codes.length; ++i) {
              foo(i);
          }
          

          这两个例子都形成了一个闭包,它引入了新的变量范围。或者,ES5 有 Function.bind 可以用于匿名函数,但尚未在所有浏览器中普遍支持。 (我在考虑 IE。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-09-04
            • 1970-01-01
            • 1970-01-01
            • 2017-05-20
            • 2018-10-31
            • 2020-07-23
            相关资源
            最近更新 更多