JS函数的执行机制

652 阅读2分钟
本文主要说一说js函数的执行机制,先来看看下面这一段代码:
let i = 0
for( i = 0; i < 6; i++){
    setTimeout(() => {
        console.log(i)
},0)
}
//结果打印出6个6
这段代码的打印结果是6个6而不是0,1,2,3,4,5。


先来解释为什么是6:
原因是setTimeout的调用时机是在for循环结束之后执行的(其实是和js的异步执行有关,setTimeout放在队列里,之后我会详细解释一篇js的单线程和他的异步机制),当for循环执行结束之后,此时的i已经变成了6(为什么不是5?原因是i = 5的时候会再进行一次i++,此时i = 6;但是这个i没有进入循环,而i的值此时确实已经变成了6),在setTimeout执行的时候将i的值打印出来。
为什么是6个?
原因是for循环执行了 0,1,2,3,4,5六次,里面的setTimeout被定义了6个(可以想象成设定了6个闹钟),所以会打印出6个。
那么如何利用上述方法打印出0,1,2,3,4,5
//方法一
for(let i = 0; i < 6; i ++ ){
    setTimeout(()=>{
        console.log(i)
    },0)
}
//0,1,2,3,4,5
//原因是let会形成一个块级作用域(关于let的详细的解释请参见文末的文章链接:理解let)
//方法二
for(var i = 0; i < 6; i++ ){
  !function (j){
    setTimeout(() => {
      console.log(j)
    },0)
  }(i);
}
//0,1,2,3,4,5
//使用立即执行函数,原因是:立即执行函数内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

文章参考链接:

js调用栈:blog.poetries.top/browser-wor…

阮一峰立即执行函数:wangdoc.com/javascript/…

方应杭真正理解let:zhuanlan.zhihu.com/p/28140450