我们先来看这样一串代码:
let a = 1
function fn1 () {
console.log(a)
}
a = 2
fn1()
let b = 1
function fn2 () {
console.log(b)
}
fn2()
b = 2
打印出的结果分别为2和1。
区别就在于函数是在变量的值发生变化之前还是之后被调用的。
所以很明显,我们能得到这样一个结论:函数执行的时机不同,结果不同。
那好,我们再来看看下面这串代码:
let i = 0
for(i = 0; i < 6; i++) {
setTimeout(() => {
console.log(i)
}, 0)
}
它的结果是啥?
那还不简单嘛,0、1、2、3、4、5呗。
不,它的结果是6个6。
??? 为啥是6个6呢?
问题就出在这个setTimeout上面。
setTimeout这个函数代表的意思是“过一会再执行”。
过一会?过多久?
setTimeout函数里还有个参数0,意思是完成手头上的活儿后立即执行。
这啥意思?
就好比,你正在LOL打排位大师晋级赛,突然听见远处飘来一句:“饭做好啦,一会过来吃饭。”
你是放下键盘鼠标立马跑过去吃饭呢,还是打完这一局再去呢?
你说当然是先去吃饭啦,我上大师就像喝水一样简单,还是吃饭更有挑战性,那你牛大了。
但setTimeout没那么牛,它选择过一会再去吃饭,先把这局晋级赛打完。
代码里的for循环就是晋级赛,console.log(i)就是吃饭。
又因为for循环执行了6次console.log(i),所以结果是6个6。
你说不行,这不符合我的预期,我就要打印出0、1、2、3、4、5。
可以,只需要把代码做一点小小的改变:
for(let i = 0; i < 6; i++) {
setTimeout(() => {
console.log(i)
}, 0)
}
这样打印出的结果就是符合大多数JS初学者预期的0、1、2、3、4、5结果。
而这是JS作出的妥协与迁就。
代码中let与for循环结合后,JS会自己加东西,在每次循环的时候会多创建一个i,目的就是得出大多数JS初学者预期的结果。
你认为JS做出这样的改变是好还是不好呢?