JS引擎线程的执行过程的三个阶段

372 阅读2分钟

概述

浏览器按顺序加载由 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环境的话,我们只需要理解宏任务事件循环的执行过程就已经足够了