js块级作用域

首先看一个常见的函数,该函数输出的是什么呢?
对的,就是5个6.
为什么会这样呢?因为setTimeout是个异步函数,每次循环的时候都会创建一个定时器,任务放到队列里,等主线程执行完才会执行定时器,这个时候循环跑完了,最后一次的 i = 5 + 1 = 6,所以输出5个6.

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

方法一

方法一使用了let,let是块级作用域变量,在每一次循环都会重新声明i;var则是在for循环之外作用域定义的变量,无法传入这个函数的执行域中。

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

方法二

使用了匿名函数,这种写法相当于声明了匿名函数之后立即调用,而且将i以参数形式传入。我们知道函数的参数传递是以值传递的,也就是说会重新copy一个与i相等的值传到匿名函数中,timer则是一个闭包,每次获取的变量都是新的i值,因此可以打印出1,2,3,4,5.

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

方法三

方法三与二差不多道理,也是一个函数传递是以值形式传递,因而每次的i值会不一样。

function printI(i) {
    setTimeout( function timer() {
       console.log(i);
    }, 1000 );}

for (var i = 1; i <= 5; i++) {
    printI(i);
}

如有不对的地方敬请指正,谢谢~

猜你喜欢

转载自blog.csdn.net/u011141492/article/details/80358504