引擎
负责整个 JavaScript程序 编译及执行过程编辑器
负责语法分析及代码生成作用域
- 收集并维护由所有声明的标识符(变量)组成的一系列查询
- 实施严格的规则,确定当前代码对标识符的访问权限
编译 —— 源代码执行前的三个步骤
JavaScript 的编译发生在执行前,而不像其他语言在构建之前
1. 分词/词法分析
-
词法单元: 将
字符组成的字符串
拆解成有意义的代码块(空格是否具有意思,要考虑空格在该语言中是否有意义) -
两者判断依据:判断是独一单元还是其他单元的一部分时,是否调用有状态的规则,是
词法分析
,否分词
。
2. 解析/语法分析
- 抽象语法树(AST):词法单元流(数组)转换成由元素逐级嵌套所组成的程序语法结构树。
-
Ps:
var a = 2
顶级节点:VariableDeclaration
└ VariableDeclaration子节点:Identifier
(a)
└ VariableDeclaration子节点:AssignmentExpression
└ AssignmentExpression的子节点:NumericLiteral
(2)
3. 代码生成 —— 将 AST 转换成可执行的机器指令
用来创建一个叫做 a
的变量 (包括分配内存等),并将一个值存储在 a
中
var a = 2
编译器
进行变量声明(如果之前没有声明)与 引擎
进行标识符(变量)查询并进行赋值。
作用域嵌套
定义:一块或函数嵌套再另一个块或函数时
引擎查找变量时,若在当前作用域查找不到,变会向上一级作用域进行查找,直至最外层作用域为止(全局作用域)。——“从外查找,不从内”
// 不报错
function foo(a){
console.log(a+b);
}
var b = 2;
foo(2) // 4
// 报错
function foo(){
var b = 2;
}
console.log(b) // b is not defined
LHS和RHS
LHS:查找变量本身(容器)
RHS:查找变量的值(源头)
function foo(a) {
console.log( a + b )
b = a
}
foo(2);
在 非严格模式
下,LHS如果找不到目标变量,会在 全局作用域
下创建一个 b 变量可供 引擎
调用