概述
浏览器按顺序加载由 script 标签分割的js代码块,完毕后立刻进入以下三个阶段。然后下一个代码块,无论是外部脚本文件(不异步加载)还是内部脚本代码块都是一样,并且都在同一个全局作用域中。
JS引擎线程的执行过程的三个阶段:
- 语法分析
- 预编译阶段
- 执行阶段
语法分析
分析该js脚本代码块的语法是否正确,如果出现不正确,则向外抛出一个语法错误(SyntaxError),停止该js代码块的执行,然后继续查找并加载下一个代码块。
预编译阶段
- 全局环境
- 函数环境
- eval
创建执行上下文
每进入一个不同的运行环境,都会创建一个相应的执行上下文(Execution Context),一段JS程序中一般都会创建多个执行上下文,js引擎会以栈的方式进行处理,形成函数调用栈(call stack),栈底永远是全局执行上下文。
创建执行上下文的三部曲:
- 创建变量对象(Variable Object),包括上下文的函数、变量、arguments
- 建立作用域链(Scope Chain)
- 确定this的指向
2.2 变量对象
函数声函数声明提前和变量声明提升是在创建变量对象中进行的,且函数声明优先级高于变量声明。
但尚未进入执行阶段,该变量对象都是不能访问的,因为此时的变量对象中的变量属性尚未赋值,值仍为undefined,只有进入执行阶段,变量对象中的变量属性进行赋值后,变量对象(Variable Object)转为活动对象(Active Object)后,才能进行访问,这个过程就是VO –> AO过程。
2.3 建立作用域链
通俗理解,作用域链由当前执行环境的变量对象(未进入执行阶段前)与上层环境的一系列活动对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。
作用域链也就是词法环境。
词法环境有两个组成部分:
- 环境记录,存储变量和函数声明的实际位置
- 对外部环境的引用,可以访问其外部词法环境
2.4 闭包
按照浏览器的理解,在函数里创建新函数,访问了外层的活动对象,就叫闭包
三. 执行阶段
网页的线程,JS引擎线程,事件触发线程,定时器触发线程,HTTP异步请求线程
微任务是在es6和node环境中出现的一个任务类型,如果不考虑es6和node环境的话,我们只需要理解宏任务事件循环的执行过程就已经足够了