3

以下面的两个例子为例。在这两个示例中,变量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那么就垃圾收集而言,它是如何工作的?GC 什么时候会删除这个值?在回调函数结束时?还是会有某种内存泄漏?

4

1 回答 1

4

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

即使setTimeout(callback, 2000)是 when iis被调用0,在 2000ms 之后(足够运行整个for循环的时间)i将变为 10,并且何时callback被调用,The first test returns: 10将显示。

但是,在创建闭包的第二个示例中,callback它本身仍然是function(){alert('...' + i);},但是由于i匿名函数中的参数隐藏了其父范围,因此iincallbacki匿名函数中的参数,而不是iin for(var i = 0; ...)

由于 JavaScript 使用按值调用,当由 设置时,i它将被“固定” ,这使得带有参数的匿名函数然后立即按值应用它(在 中)。callback(function(i){...}(i))iifor(var i ...)

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

于 2013-08-03T06:15:49.403 回答