1.1 编译原理函数
传统编译步骤性能
分词/词法分析(拆分红一个个词法单元)——>解析/语法分析(词法单元流转化为抽象语法树)——>代码生成(将抽象语法书(AST)转化为可执行代码(机器指令))优化
js引擎比上述要复杂,在各个阶段会有特定步骤来对性能进行优化,好比冗余元素。spa
其余不少语言的编译多发生在构建以前,而js大部分状况下的编译是发生在代码执行前的短短几微秒内,没有其余语言编译器那样有那么多的时间进行优化,因此js引擎想了各类办法来保证性能最佳(好比JIT,能够延迟编译甚至实施重编译)。blog
1.2 理解做用域作用域
以var a = 2为例,执行这个语句须要引擎,编译器,做用域的配合。编译器
编译器查询方式io
以LHS和RHS为例,LHS查询是视图找到变量的容器自己,并对去赋值,而RHS是简单的查找某个变量的值。console
好比console.log(a),这里对a的引用就是RHS,并无进行任何赋值。编译
而a=2,这里对a的引用就是LHS,并不关心当前的值是什么,只是要为 '=2' 这个赋值操做找到一个目标。
注:eg:foo(a)中实际上含有一个隐式 'a=2' 操做,不要忽略这一个LHS查询。
注:函数声明function foo(a) {...}不能简单的理解为LHS查询和赋值操做(var foo,foo = function(a){...}),由于编译器能够在代码生成的同时处理声明和值的定义。
1.4 异常
在变量尚未声明的状况下,这两种查询的行为是不一样的。RHS若是找不到该变量,引擎会抛出ReferenceError的错误,而LHS则会在全局做用域下建立一个具备该名称的变量,并将其返还给引擎(须要程序运行在非'严格模式'下,'严格模式'下,引擎会抛出同RHS相似的ReferenceError异常)。