如果你也在面试找工作,那么也一定遇到过这道for循环打印结果的题,下面我们来探讨下
var循环
for(var i = 0; i < 10; i++) {
setTimeout(function(){console.log(i)});
}
先把答案写出来
下面来讲一下原因:
划重点 ① var ②setTimeout()
重点1:你需要了解一下变量提升(hoisting)
var变量声明,无论发生在何处,都在执行任何代码之前进行处理。
用var声明的变量的作用域是它当前的执行上下文,它可以是嵌套的函数,也可以是声明在任何函数外的变量。如果你重新声明一个 JavaScript 变量,它将不会丢失其值。
然后上面的代码其实是这样的
var i = 0;
for (; i < 10; i++) {
setTimeout(function () {
console.log(i)
})
}
重点2、setTimeout()
它总是在当前的同步代码执行完成后开始运行。(出自简书---一斤代码)
可以加入log进行跟踪验证:、
var i = 0;
for (; i < 10; i++) {
console.log('+++++', i)
setTimeout(function () {
console.log(i)
})
}
执行结果:
+++++ 0
+++++ 1
+++++ 2
+++++ 3
+++++ 4
+++++ 5
+++++ 6
+++++ 7
+++++ 8
+++++ 9
10
10
10
10
10
10
10
10
10
10
由此可见,当开始执行setTimeout()
中的代码时for
循环外面的变量i
就已经变成了10
,使用console.log(i)
从作用域查找到的i
值就是10
,然后循环十次10。
let循环
ES6的let/const,简单来说let/const是声明块级作用域的变量
for(let i = 0; i < 10; i++) {
setTimeout(function(){console.log(i)});
}
下面是打印结果: