为什么for中闭包需要内部引用var定义的i才能打印出12345?

有幸看到这位博主的文章 for循环中闭包问题

但是不理解:
这里,为什么会打印66666

 for (var i=1; i<=5; i++) {
  (function() {
     setTimeout( function timer() {
        console.log( i );
     }, i*1000 );
   })();
}
/*
    6
    6
    6
    6
    6
*/

而这里,仅仅多增加了一步 var j = i,或者说将i当作参数传进去,结果就大不一样。
为什么呢?
上面第一段代码中仅有的 console.log(i)不算事闭包内对外部函数的引用吗?

 for (var i=1; i<=5; i++) {
    (function() {
        var j = i;//保存外部变量
        setTimeout( function timer() {
            console.log( j );
        }, j*1000 );
    })();
}
/*
    1
    2
    3
    4
    5
*/
//代码改进:(将i当参数传进去)
 for (var i=1; i<=5; i++) {
    (function(j) {
        setTimeout( function timer() {
            console.log( j );
        }, j*1000 );
    })( i );
}
阅读 2.5k
2 个回答
for (var i=1; i<=5; i++) {
    (function(j) {
        setTimeout( function timer() {
            console.log( j );
        }, j*1000 );
    })( i );
}

这样写,相当于在函数作用域中创建了变量j,每循环一次,就创建一个函数作用域。此时每个函数作用域中都会保存一个变量j

for (var i=1; i<=5; i++) {
  (function() {
     setTimeout( function timer() {
        console.log( i );
     }, i*1000 );
   })();
}

这样写,是因为你这个i是全局作用域下的,每次循环i都会变化,同步代码执行完之后,会执行延时器,里面的i是在全局作用域中,此时已经变成了5.

重点理解函数作用域和全局作用域,如果把那个var改成let也可以(这就引入了局部作用域的概念)。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏