JS 函数的执行时机

128 阅读2分钟

一个函数的调用(执行)时机不同,那么结果也不同.
函数的执行结果是什么取决于函数在什么时机调用!
函数体本身写在哪跟执行结果无关!!!因为函数要执行了才会有结果!!!

先了解一下定时函数 setTimeout(func,time) :
setTimeout(func,time) 是在time(毫秒单位)时间后执行func函数。浏览器引擎按顺序执行程序,遇到setTimeout会将func函数放到执行队列中,等到主程序执行完毕之后,才开始从执行队列(队列中可能有多个待执行的func函数)中按照time延时时间的先后顺序取出来func并执行。即使time=0,也会等主程序运行完之后,才会执行

为什么如下代码会打印 6 个 6

let i = 0
for(i = 0; i<6; i++){
  setTimeout(()=>{
    console.log(i)
  },0)
}

原因:定时函数被加入执行队列,等for循环结束之后,再去调用定时函数。for循环结束之后,i的值已经从0变为6,i等于6之后,六次的定时函数都会共用i=6这个值并打印。所以最终会分别打印6个6。

怎么修改以上代码可以打印0到5呢 ?

把以上代码的 let i = 0 放到for循环内即可!
即:

for(let i = 0; i<6; i++){ //注意现在let i = 0在for循环内!
  setTimeout(()=>{
    console.log(i)
  },0)
} //结果为分别打印出0,1,2,3,4,5

原因 : JS 在 for 和 let 一起使用的时候会加东西, 每次进入循环时都会把 i 复制一份, console.log(i)里的i变成了不是会变的 i , 即: 当i分别等于0到5时, JS 都会把 i 留在 for 循环这个空间内并复制一个 i , 不跟随新的 i 变化, 所以六次循环一共生成了6个新的 i , 即i被复制了6遍, 并分别通过六次定数函数打印出来. (再加上最开始let i=0这个i, 其实最后总共有7个i)

还有什么方法能打印出0到5吗 ?

方法:将setTimeout进行封装 ! 改成这样即可:

let i = 0
var f = function(x){
    setTimeout(()=>{
    console.log(x)
    },0)
}
for(i = 0; i<6 ;i++){
    f(i)
} //结果为分别打印出 0,1,2,3,4,5

原理:将setTimeout进行封装,此时定时函数的变量作用域就变为f函数代码块内,每次for循环传给定时器的i值都会变为定时函数的私有变量值。