Rumah  >  Soal Jawab  >  teks badan

javascript - 关于闭包的问题

为什么这段代码输出不是10个9,而是0-9?

function test() {
    for (var i = 0; i < 10; i++) {
        setTimeout(console.log(i), 1000);
    }
}

test();

讲闭包的时候经常会用到这个例子(代码不完全相同)。为什么i的值不等于循环结束的9?
下面这个例子是10个9,区别在什么地方?加一层匿名函数不应该形成局部作用域吗,为什么取得了相反的效果?

function test() {
    for (var i = 0; i < 10; i++) {
        setTimeout(function() {
            console.log(i)
        }, 1000);
    }
}
test();

=========================
给后来碰到同样问题的同学:
用户『kikong』和『苏哈哈哈』的答案都是比较好的,思路都很清晰。
其他用户答案也是对的,只是表述有点简略,看懂了就能理解。
我本来是想试试『let』,没想到牵涉出这个问题。

大家讲道理大家讲道理2770 hari yang lalu405

membalas semua(4)saya akan balas

  • 天蓬老师

    天蓬老师2017-04-11 10:10:33

    function test() {
        for (var i = 0; i < 10; i++) {
            setTimeout(console.log(i), 1000);
        }
    }
    
    test();

    ==》

    function test() {
        for (var i = 0; i < 10; i++) {
            console.log(i);
            setTimeout(undefined, 1000);
        }
    }
    
    test();

    1.setTimeout作为一个函数,在调用的时候需要对传入的参数求值;
    2.setTimeout并不表示本身会被延迟执行
    3.setTimeout是为指定的传入函数对象指定一个调用的时间点,并注册到JS的事件执行队列中

    console.log(i)作为一个调用语句在循环过程中被执行,返回的结果为undefined;

    balas
    0
  • 巴扎黑

    巴扎黑2017-04-11 10:10:33

    我觉得是console.log(i)这句话执行了,所以你那里相当于setTimeout(0,1000),然而是setTimeout(1,1000)......

    balas
    0
  • 大家讲道理

    大家讲道理2017-04-11 10:10:33

    第一段代码可以理解为

    function test() {
        for (var i = 0; i < 10; i++) {
            setTimeout(console.log(i), 1000);
        }
    }
    
    test();
    
    

    在声明阶段保存了i的值,所以,会立刻的打出保存的i值,即0-9

    第二段代码没有使用闭包,是在执行阶段才获取的i值,此时的i已经是10,所以是在一秒后才输出10个10.

    balas
    0
  • 巴扎黑

    巴扎黑2017-04-11 10:10:33

    好吧,答晚了。看采纳的答案即可。

    第一个例子。你执行了10次console.log(),跟setTimeout一点关系都没有。setTimeout的第一个参数应该传入函数,你传的是console.log()执行后返回的undefined

    第二个例子。你给setTimeout传入一个匿名函数,匿名函数形成了闭包,虽然test执行结束了(此时i已经变成10了),但是闭包保存了这次test执行时的i变量。然后setTimeout一秒钟后执行该匿名函数,再去获得这个i变量,打印,就是10咯。

    balas
    0
  • Batalbalas