如果你也在面试找工作,那么也一定遇到过这道for循环打印结果的题,下面我们来探讨下
- 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。
ES6的let/const,简单来说let/const是声明块级作用域的变量
- for(let i = 0; i < 10; i++) {
- setTimeout(function(){console.log(i)});
- }
下面是打印结果: