代码之家  ›  专栏  ›  技术社区  ›  Parand

带闭包的JavaScript作用域:帮助我理解

  •  5
  • Parand  · 技术社区  · 15 年前

    运行以下代码:

    for (var i=0; i<3; i++) { 
       setTimeout( function() { console.log(i); } , 500 ); 
    }
    

    输出“3”三次。它输出的是 i 创建内部函数时。

    在函数被定义为与它的最终值相反的时候?

    4 回复  |  直到 14 年前
        1
  •  6
  •   palswim    14 年前
    for (var i=0; i<3; i++) {
       setTimeout( function(val) { return function() { console.log(val); } }(i), 500 );
    }
    

    所以,至少 setTimeout 时间(定义函数时) ),我们调用匿名函数 val 作为参数。这将为每个函数调用创建一个闭包,存储 瓦尔 self-invoking function ,这将创建一个 closure .

    在您提供的代码中,代码创建了一个闭包,但是对于整个代码的更大范围,所以 i 是整个代码的局部变量,这意味着在运行时,匿名函数将使用该变量 其他代码使用的。

        2
  •  4
  •   Mark Bolusmjak    15 年前
    function f(i){
      return function(){console.log(i);};
    }
    
    for (var i=0; i<3; i++) { 
       setTimeout( 
         f(i)
       , 500 ); 
    }
    
        3
  •  2
  •   Community CDub    8 年前

    显式闭包的现代替代方法是 Function#bind . 一旦你成功了 hacked in support

    for (var i=0; i<3; i++) {
        setTimeout(function(i) { console.log(i); }.bind(window, i), 500);
    }
    

    window 是指 this 将在函数中(您不需要 在这里,我们只使用默认的全局对象)。如果您只是在调用另一个函数/方法,比如 console.log ,可以使用它完全删除函数表达式:

    for (var i=0; i<3; i++) {
        setTimeout(console.log.bind(console, i), 500);
    }
    
        4
  •  1
  •   David Murdoch    15 年前

    for (var i=0; i<3; i++) {
       (function(val){
           setTimeout(function() {
               console.log(val);
           },500)
       }(i));
    }