JS 函数的执行时机不同,那么其结果也不同,这次我们就来讲一讲 JS 函数的执行时机。
我们来通过一些案例逐步了解 JS 函数的执行时机。
let a = 1
function fn(){
console.log(a)
}
// 这段代码,无法确定打印出的是什么,因为 fn 没有被调用
let a = 1
function fn(){
console.log(a)
}
fn()
// 1
let a = 1
function fn(){
console.log(a)
}
a = 2
fn()
// 2
// a 是一个全局变量,fn 被调用的时候,a 的值变成了 2,此时打印的结果为 2
let a = 1
function fn(){
console.log(a)
}
fn()
a = 2
// 1
// 代码先执行 fn ,然后对 a 的值进行修改,所以打印出的值还是 1
let a = 1
function fn(){
setTimeout(()=>{
console.log(a)
}, 0)
}
fn()
a = 2
// 2
// setTimeout 是一个延迟执行的异步函数,即使设置延迟时间为 0 ,也要等所有代码执行完才会执行 setTimeout 内的函数,所以在执行 console.log(a) 时,此时 a = 2 已经执行完毕,所以值为 2
接下来,我们来看一个面试题
let i = 0
for(i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
}, 0)
}
这段代码的打印结果为 6 个 6,由于 setTimeout
会延迟执行,每次循环执行一次 setTimeout
,在循环结束时,i 的值为 6,此时执行 6 次 console.log(i)
,所以打印出 6 个 6。
那么,我们如何通过 setTimeout
来打印出 0、1、2、3、4、5 呢?
目前,我可以通过如下两种方式来解决这个问题。
for(let i = 0; i < 6; i++){
setTimeout(()=>{
console.log(i)
}, 0)
}
// 0、1、2、3、4、5
// 通过 for let 配合,JS 会在 for 循环里再创建一个 i 变量,用于临时存储。
// 而 setTimeout 接收到的 i 就是这个临时被创建的变量 i,所以结果为 0、1、2、3、4、5
let i = 0
for(i = 0; i < 6; i++){
!(function (i){
setTimeout(()=>{
console.log(i)
}, 0)
}(i))
}
// 0、1、2、3、4、5
// 这种方法我们可以理解为第一种方法对临时变量的解释
// 通过立即执行函数,来获取一个临时变量 i ,根据作用域的就近原则,打印的 i 就是 临时变量 i
以上就是打印 0、1、2、3、4、5 的方法,如有其他方法,欢迎补充!