JavaScript解析器执行三部曲
1.基本的语法检测
当浏览器解析JS代码时,第一步是大概扫描代码的语法是否符合基本规范,如果少了括号,或者语法格式错误,会直接报错。
报错一般为:
Uncaught SyntaxError: expected expression
2.预解析
2.1前言
这个过程是最复杂的过程,中间会讲到作用域和作用域链这块知识点,我在学习中也是遇到了很多坑,我将在下个博客重点讲解作用域和作用域链。
关键字:全局对象-Global Object,局部对象(活跃对象-)--Active Object
2.2解析过程
全局预解析:
①在文中顶部创建一个全局对象---Global Object。(后面我将简称为GO)
②寻找var 关键字,将找到的var声明的变量名提前(变量提升),作为GO对象的属性成员,值为undefined。
③寻找function关键字,将找到的函数体提前,作为GO对象的方法,方法名为函数名,方法体为函数体。
④如果遇到重名,因为在对象中是没有重名的属性的,必然会有覆盖的情况。
分以下情况处理:
1.var声明的变量名与变量名重名,按照上下文从上到下的顺序,后声明的覆盖先声明的。
2.function声明重名,则按照上下文从上到下的顺序,后声明的覆盖先声明的。
3.var声明的变量和function声明的变量重名,则function覆盖var。
这里以第三种情况(这种情况是最坑的)举个例子
//分析过程
/*
全局预解析:
GO = {
x:undefiend,
y:undefined,
z:undefined,
add:function{
return n = n+3
}
//之所以是第二个函数体就是因为第一个函数体被覆盖了
}
*/
var x = 1,y=0,z = 0;
function add(n){
return n = n+1
}
y = add(x);
function add(n){
return n = n+3
}
z = add(x);
console.log(y,z)
当这四步走完,全局预解析结束,解析器开始从上到下逐行执行代码也就是进入第三个阶段
3.执行代码
执行代码时会遇到函数调用,此时解析器会在全局AO中找到被调用的函数体,并进行局部解析。
注意:函数预解析与全局预解析类似,但千万不要记混了
函数预解析过程:
①在函数顶部创建一个活跃对象---Active Object。(后面我将简称为AO)
②寻找参数,函数的形参作为AO对象的属性名,
如果有实参,则实参作为AO对象的属性值,
如果没有传递实参默认为undefined。
②寻找var 关键字,将找到的var声明的变量名提前(变量提升),作为AO对象的属性成员,值为undefined。
③寻找function关键字,将找到的函数体提前,作为AO对象的方法,方法名为函数名,方法体为函数体。
④如果遇到重名,因为在对象中是没有重名的属性的,必然会有覆盖的情况。
分以下情况处理:
1.var声明的变量名与变量名重名,按照上下文从上到下的顺序,后声明的覆盖先声明的。
2.function声明重名,则按照上下文从上到下的顺序,后声明的覆盖先声明的。
3.参数,var声明的变量和function声明的变量重名,则function覆盖它们。
4.如果AO中存在参数与参数,参数与变量(重名),则忽略,不做任何影响:比如参数名和变量名相同,那么不管这个变量名。
其实就是可以记作,function覆盖所有,其他的忽略
以上就是JS预编译过程的全部过程,有什么问题欢迎大家一起讨论哦!