今天是一个复习———预编译,这么久没有学习了都快要忘记了
JavaScript运行三部曲
- 语法分析
- 预编译
- 解释执行
最先会对整个代码全部检测是否有语法错误,在进行预编译,最后准备就绪后执行代码。那么还能记得预编译的过吗?
预编译的四步先来一遍:
- 函数执行的前一刻创建活动对象AO
- 将var关键字声明的变量和形参作为活动对象的属性名复制undefined ,如果有函数重名不新增直接替换
- 将形参和实参统一
- 检测到function声明的函数,将函数名作为AO对象的属性名,赋值函数体有函数重名不新增直接更新
这个完了之后,再来上代码一步步按照编译过程进行
例:
function test(){
console.log(b);
if(a){
var b = 100;
}
console.log(b);
c = 234;
console.log(c);
}
var a;
test();
a = 10;
console.log(c);
1.创建A0对象
AO{}
2.找形参和变量作为AO对象属性名,复制undefined
AO{
c: undefined
}
3.将实参和变量统一
AO{
b :undefined
a : undefinde
c: 234
}
4.在函数体力里面找函数声明,复制函数体
AO{
b :undefined
a : undefinde
c: 234
test()
}
输出结果:
预编译执行完之后进行:
首先执行第一句console.log(b),没有b的声明此时输出 undefined,再到if ,因为没有a的声明所以var b = 100 这一步没有赋值上,所以再到console.log(b) 依然是undefined,在console.log© c 有赋值,但是没用进行声明 c会成全局,所以函数外面的c也会等于 234
再来看全局GO,GO和AO执行步骤是一样的
- 创建一个GO对象,即window对象
- 在找变量声明赋值为undefined,有重名的不新增直接替换,全局预编译没有形参和实参
- 在全局里找函数声明,函数声明赋值到全局的GO,有重名不新增直接替换;
function b(a){
console.log(a);
}
b(1);
console.log(a);
var a = 2;
console.log(a);
1.创建活动对象GO
GO{}
2.找变量声明
GO{
a:undefined
}
3.找函数声明
GO{
a : undefined
b(){}
}
输出结果
当函数b(1),执行之后会把值赋值给a,函数b里面的a 输出是1,此时函数执行完成会释放,再次console.log(a) 在GO中此时还没有 声明a,会输出undefined,在下一次console.log(a)的时候已经声明了a 所以输出 2