首先看最简的题目:
for(var i=0; i++; i<2) {
setTimeout(() => console.log(i))
}
输出结果是什么?
由于i
是通过var
定义的,它是一个全局变量,当log
的时候内存中只存在一个i
,并且这个i
通过循环已经变成了2,所以输出结果是输出两次2
对题目进行改造。将var
换为let
:
for(let i=0; i++; i<2) {
setTimeout(() => console.log(i))
}
输出结果是什么?
通过let
定义的i
是一个块级作用域的变量,实际上在for
循环的过程中,每一次循环都会生成一个新的i
,它是作用域旨在当次循环内部,所以log
的时候打印的是每一次生成的i
,所以输出结果是0
和1
再看一个基础知识,,
表达式
let a = (1, 2);
a
的值是什么?
JS中,逗号操作符的作用是对它的每个操作数求值(从左到右),并返回==最后一个==操作数的值。所以a
的值是2
所以引出了真正的题目:
for(let i=(setTimeout(() => console.log(i), 2333) ,0);
i++;
i<2) {
setTimeout(() => console.log(i))
}
在2333秒后会输出结果是什么?
这道题考察的关键点是逗号操作符和for
循环中的变量作用域
在for
循环中,第一部分声明了变量i
,这个变量i是一个具有单独作用域的i
, 在i++
时并没有改变它的值,每次i++
都会生成一个新的i
, 上面提到的每次循环新生成的i就是在这个步骤生成的
回到题目中,在声明i
的语句中,由于逗号操作符的关系,i
的值为0
, 此时0
就传入了setTimeout
中,随着循环进行这个i
并没有发生改变,所以在2333秒后打印的值就是0
, 也就是一开始定义的i
的值