for循环的范围问题

时间:2012-10-26 21:02:01

标签: javascript scope

对我来说这不是一个问题。我只想知道如何正确地做到这一点,而不是解决方法。好吧,如果我们使用for()和一些延迟事件,则只考虑最后一个值。

测试http://jsfiddle.net/39dQV/

// Using only i (does not work)
for(var i=0; i<10; i++) {
    setTimeout(function() {
        test1.textContent = i;
    }, i * 1000);
}

// Private scope to i (does not work either)
for(var i=0; i<10; i++) {
    var x = i;

    setTimeout(function() {
        test2.textContent = x;
    }, i * 1000);
}

// Callback scope (workaround)
function set_textContent(i) {
    setTimeout(function() {
        test3.textContent = i;
    }, i * 1000);
};

for(var i=0; i<10; i++) {
    set_textContent(i);
}​

我需要做什么才能使其正常工作,即:考虑i的当前值,而不是按时间更改的最后一个值?

1 个答案:

答案 0 :(得分:2)

您的解决方案并非真正的“解决方法”,它就在最佳方式附近:

for(var i=0; i<10; i++) {
    setTimeout(function() {
        test1.textContent = i;
    }, i * 1000);
}

无法工作!当函数执行时,我在本地范围内不再定义。

for(var i=0; i<10; i++) {
    var x = i;

    setTimeout(function() {
        test2.textContent = x;
    }, i * 1000);
}

这里的情况相同,x在循环中是局部的。

您的变量需要一个自己的范围。定义这样一个范围的唯一方法是将一个超时函数的定义封装在一个闭包或函数中,就像你用第三种方式那样。

我写的是这样的:

for(var i=0; i<10; i++) {
    ( function( i ) {
        setTimeout(function() {
            test1.textContent = i;
        }, i * 1000);
    } ( i ) };
}

闭包定义了自己的范围,因此存储了i的值。

有关更深入的信息,请参阅:http://www.javascriptenlightenment.com/(我喜欢它)