JS的运行分三部:语法分析 ➡️预编译➡️解释执行
语法分析:JS引擎先通篇扫描一遍,查看是否有低级语法错误
(函数)预编译详解:
先来看看这句代码的输出情况
console.log(a); //会输出undefined
var a = 5;
并未发生报错,但也没有输出a的值。
这是因为预编译会将 变量的声明提升到逻辑的最前面。也就是将 var a = 5 拆分成
var a;和 a = 123;然后把var a 提升到最前面。
同理,预编译也会将函数声明整体提升。下面这段代码不会报错。
test()
function test(){
console.log('不报错')
}
那要是遇到这种恶心的代码呢
function fn(a) {
console.log(a);
var a = 123;
console.log(a);
function a() {}
console.log(a);
var b = function () {}
console.log(b);
function d() {}
}
fn(1);
so EZ!只需要理解预编译四部曲即可:
1.创建AO(Activation Object)对象 (执行期上下文,其实就是一个作用域).
2.找到形参和变量声明,并将其作为AO对象的属性名,值为undefined.
3.将实参与形参相统一.
4.在函数体内找到函数声明,并将值赋到AO对象.
现在就用这四部来分析一下上面的代码
第一步:创建
AO{
}
第二步:
AO{
a:undefined,
b:undefined
}
第三步:
AO{
a:1;
b:undefined
}
第四步:
AO{
a:function a(){},
b:undefined,
d:function d(){}
}
然后开始解释执行 (解释执行时预编译看过的代码就不会再次执行来)
第一个console.log(a);输出 function a(){}
执行 a = 123;
第二个console.log(a);输出123
function a(){}预编译看过了 就不会再执行了
第三个console.log(a);输出123
执行b = function(){}
第四个console.log(b);输出function (){}
(全局)预编译
全局的预编译分三步
1.生成一个GO(Global Object)对象(window就是GO)
2.找到形参和变量声明,并将其作为GO对象的属性名,值为undedined.
3.找到函数声明,并将值赋到GO对象.
网友评论