Javascript - 帮助理解变量行为

时间:2013-08-03 06:00:44

标签: javascript closures

采取以下两个例子。在两个示例中,变量i被指定为0到9.在第一个示例中,在调用超时函数时,i已经被赋值为9.我不知道设置超时时i的值。

for(var i = 0; i < 10; i++) {
    var callback = function() {
        alert('The first test returns: ' + i);
    };

    if(i === 0) setTimeout(callback, 2000);
}

在第二个选项中,我们可以通过将i传递给新的上下文来保留for(var i = 0; i < 10; i++) { var callback = (function(i) { return function() { alert('The second test returns: ' + i); } })(i); if(i === 0) setTimeout(callback, 2000); } 的值(如果这个术语不正确,请纠正我)。

0

第二个例子给了我期望的值{{1}} - 那么就垃圾收集而言,这是如何工作的呢? GC会在什么时候删除此值?在回调函数结束时?或者会有某种内存泄漏?

1 个答案:

答案 0 :(得分:4)

在第一个示例中,callback是函数function(){alert('...' + i);},其中i是定义callback的范围内的变量,即i in for(var i = 0; ...)

即使在setTimeout(callback, 2000)i时调用了0,在2000毫秒之后(这是足够的时间来运行整个for循环,i将成为callback 10,当调用The first test returns: 10时,将显示callback

但是,在进行闭包的第二个示例中,function(){alert('...' + i);}本身仍为i,但由于匿名函数中的参数i会影响其父作用域,{{1} } callback中的参数是匿名函数中的参数i,而不是i中的for(var i = 0; ...)

由于JavaScript使用按值调用,icallback设置(function(i){...}(i))i将被“修复”,这会生成带参数i的匿名函数然后立即按值for(var i ...)(在{{1}})中应用它。

GC在这里没有任何作用。 (GC的不同行为 - 除了内存使用和时间 - 意味着GC中存在错误。)