预编译
js执行顺序: 词法/语法分析 预编译 解释执行
js中存在预编译
function demo() {
console.log('I am demo');
}
demo(); //I am demo
test(); // I am test
//分析: 由于存在预编译,test函数可以执行
function test() {
console.log(" I am test")
}
var a;
console.log(a) //undefined
a = '123'
预编译发生在代码执行的前一刻
预编译的步骤:
1,创建执行期上下文 activation object,即AO
2,找形参和变量声明,将形参和变量声明做为AO的属性名,尚未赋值,值为undefined
3,将形参和实参相统一, 即把实参的值传到形参里面去
4,在函数体里面找函数声明,赋值函数体
实例
function demo(a, b){
console.log(a)
c =0;
var c;
a = 1;
b = 3;
console.log(d)
function d(){
console.log(d)
}
function e(){
console.log(e)
}
}
demo(1)
// 1.创建AO对象{}
// 2.找形参和变量声明
AO = {
a:undefined,
b: undefined,
c: undefined,
}
//3. 形参实参想统一
AO = {
a:1,
b: undefined,
c: undefined,
}
// 4.在函数体里面找函数声明,值赋函数体
AO = {
a:1,
b: undefined,
c: undefined,
d:function d(){
console.log(d)
},
e: function e(){
console.log(e)
}
}
// 5.解释执行
预编译(脚本代码块script执行前)
1,生成GO
2. 查找全局变量声明(包括隐式全局变量声明,省略var声明),变量名作全局对象的属性,值为undefined
3. 查找函数声明,函数名作为全局对象的属性,值为函数引用
代码:
//GO{
// global : 100,
// fn : function(){...}
//}
global = 100;
function fn(){
console.log(global);//undefined
global = 200;
console.log(global);//200
var global = 300;
}
fn();
var global;
//AO{
// global : 300
//}
预编译要点
首先预编译导致的基于两点
1.变量的声明提升
首先var a = 123;,这个叫做变量声明和变量赋值,系统首先会把变量声明var a;提升到最前面。
2.函数声明整体提升
就是说声明一个函数,不管在它上面调用函数还是在下面调用函数,都可以,因为系统总是会把函数提到逻辑的最前面,这样不管在哪里调用这个函数在本质上都是在它下面调用。