JS语法:编译执行过程 语法树 AO VO 作用域链

前端之家收集整理的这篇文章主要介绍了JS语法:编译执行过程 语法树 AO VO 作用域链前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

JavaScript的编译过程与运行机制

javascript编译阶段

编译阶段:
对于常见编译型语言(例如:Java)来说,编译步骤分为:词法分析->语法分析->语义检查->
代码优化和字节生成
对于解释型语言(例如JavaScript)来说,通过词法分析和语法分析得到语法树后,就可以开始解释执行了。

对于javascript这样的解释性语言,其实只有 前面的词法分析还有语法分析,词法分析就是挨个字符的去扫描源代码,把关键token识别出来。之后通过语法分析,建立上下文关系语法树ast(abstract Syntax tree),解释器再根据语法树开始解释执行。所以会比c,c++这类的慢很多。

var a = 1,b=2;

/*解析后的语法树
{
"type": "Program","body": [
{
"type": "VariableDeclaration","declarations": [
{
"type": "VariableDeclarator","id": {
"type": "Identifier","name": "a"
},"init": {
"type": "Literal","value": 1,"raw": "1"
}
},{
"type": "VariableDeclarator","name": "b"
},"value": 2,"raw": "2"
}
}
],"kind": "var"
}
]
}

*/

json格式的语法树,每个对象就是一个节点(Node)。可以看到每个节点都有一个type属性用来标识当前节点的类型。

Program类型,是语法树的根节点,只有一个。它具有body属性包括所有的语法节点。然后整个的var a = 1,b=2;是一个变量声明语句(VariableDeclaration)。这个语句里面有一些变量声明符(VariableDeclarator),这边就是a=1和b=2;变量声明符下面有两个属性,分别是id和init。也就是对应的左边的被赋值者和右边的值。Identifier与Literal都可以表示最小的单位,他们不再包含其他节点。

函数的VO

在javascript引擎在将语法检查后正确后生成的语法树复制进来之后,javascript引擎会对语法树当中的变量声明、函数声明以及函数的形参进行属性填充,这过程是发生在执行代码之前,也就是为真正的解析阶段做好准备,这既是为什么此阶段叫“预解析”的原因了(一边填充一边执行,一句句来)。

在解释执行阶段,遇到变量需要解析时,会首先从当前执行环境的活动对象中查找,如果没有找到而且该执行环境的拥有者有prototype属性时则会从prototype链中查找,否则将会按照作用域链查找。遇到var a = ...这样的语句时会给相应的变量进行赋值(注意:变量的赋值是在解释执行阶段完成的,如果在这之前使用变量,它的值会是undefined)

案例题

理解变量提升是需要结合实例的.

var a = 1;
console.log(a); //1
var a;
console.log(a); //1
var a = undefined;
console.log(a); //undefind

猜你在找的程序笔记相关文章