编译原理

传统编译语言的流程中,编译会执行三个步骤:

  1. 分词/词法分析 这个阶段将代码分解成词法单元,比如var a = 2,分解成var、a、=、2
  2. 解析/语法分析 将词法单元转换成抽象语法树(AST)
  3. 代码生成 将抽象语法树转换成可执行代码

JavaScript的编译有什么不同

JavaScript的编译过程不是发生在构建之前,而是发生在执行前的几微秒或者更短的时候,因此,JavaScript不会像其它语言那样有大量的时间去做优化。

理解作用域

三个角色

  • 引擎:负责js编译和执行的整个过程
  • 编译器:负责语法分析和代码生成
  • 作用域:负责收集和维护由所有的声明标识符组成的一系列查询,有一套严格的规则

变量的赋值操作

变量的赋值操作会执行两个动作,首先编译器会在当前作用域中声明一个变量,如果这个变量之前没有声明过, 然后在运行时引擎会在作用域中查找该变量,如果能够找到就对它赋值。

LHS 和 RHS

  • LHS:赋值操作左侧查询,查找到该变量本身,以便进行赋值操作。如果LHS查询失败,在严格模式下会抛出TypeError,在非严格模式下,会创建一个全局变量。
  • RHS: 赋值操作右侧查询,查找某个变量的值。如果RHS查询失败,抛出ReferenceError

作用域嵌套

作用域是根据名称查找作用域的一套规则,在当前作用域没有找到某个变量时,引擎就会到外层作用域进行查找,直到最外层的全局作用域。

什么是作用域

作用域是一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找