时机不同,结果不同。 犹如刻舟求剑。
例子 1
- 代码
let a =1
function fn(){
console.log(a)
}
- 问打印出多少?不知道!都还没调用呢
例子 2
- 代码
let a = 1
function fn(){
console.log(a)
}
fn()
- 问打印出多少?1
例子 3
- 代码
let a = 1
function fn(){
console.log(a)
}
a = 2
fn()
- 问打印出多少?2!
- 函数没执行就让a = 2了哦
例子 4
- 代码
let a = 1
function fn(){
console.log(a)
}
fn()
a = 2
- 问打印出多少
- 答为1
例子 5
- 代码
let a = 1
function fn(){
setTimeout(()=>{
console.log(a)
},0)
}
fn()
a = 2
- 问打印出多少
- 2
- setTimeout 意思是尽快(就像你打游戏,先打完才做),自然,console.log在a=2之后
例子 6
- 代码
let i = 0
for(i = 0;i<6; i++){
setTimeout(()=>{
console.log(i)
},0)
}
- 问打印多少
- 不是0,1,2,3,4,5
- 而是6个6
- 又是因为setTimeout,先把for循环搞完再console.log(定闹钟)
例子 7
- 代码
for(let i =0; i<6; i++){
setTimeout((){
console.log(i)
},0)
}
- 问打印出多少
- 答案
- 是 0、1、2、3、4、5
- 因为 JS 在for 和 let 一起用的时候会加东西
- 每次循环会多创建一个 i (真有你的啊JS)
说结论
- 函数被调用才会开始执行
- 遇到setTimeout时,由于这货是会让代码继续执行下去直到完成才执行setTimeout内容,所以需要for let配合达成我们想要的结果。不用for let 就会出现6个6情况
- 不用for let行不行?行
不用for let又用setTimeout,又想012345的结果
- 已知setTimeout等延迟函数的回调会在循环结束时才会执行。或者说setTimeout会延后他作用的代码
- 那么我们试试让setTimeout认为他不在一个循环里
function timer1(i) {setTimeout( console.log(i),0)}
for(i = 0; i < 6; i++){timer1(i)}
- woc,这是为什么呢
- js中 function 可以提供一段独立的作用域,那我们就可以通过在迭代内使用function会为每个迭代都生成一个新的作用域,使得延迟函数的回调可以将新的作用域封闭在每个迭代内部,每个迭代中都会含有一个具有正确值的变量供我们访问。
- 或者说,在function作用域屏蔽了外部的循环,setTimeout就只能乖乖执行了。