JavaScript预编译
首先了解一下js运行步骤
js运行三部曲
① 语法分析
② 预编译
③ 解释执行
预编译
我们都知道函数声明整体提升,变量声明提升,也就是说在你写一个函数声明,不管你写在哪里,系统都会把函数声明提升到逻辑的最前面;变量声明只会讲声明提前,并不会将赋值提前。例如:
document.write(a);//undefined
var a = 123;
至于为什么会出现这种情况,这就涉及了js的预编译了。至于预编译发生在什么时候,它发生在函数或代码执行之前,并且不仅发生在函数体内还发生在全局中。
函数预编译
① 创建AO(Activation Object)对象
② 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
③ 将实参值和形参统一
④ 在函数体里面找寻函数声明,值赋予函数体
注意点
以下创建函数的方法不是函数声明,这是函数表达式
var a = function () {}
函数预编译例子
function test(a,b){
console.log(a); //1
c = 0; //c变成了0
var c;
a = 3; //a变成3
b = 2; //b变成2
console.log(b); //2
function b(){}
function d(){}
console.log(b); //2
}
//第一步:生成AO
//AO{
//}
//第二步:找形参和变量声明
//AO{
// a : undefined,
// b : undefined,
// c : undefined,
//}
//第三步:实参值和形参统一
//AO{
// a : 1,
// b : undefined,
// c : undefined,
//}
//第四步:找函数声明
//AO{
// a : 1,
// b : function b(){},
// c : undefined,
// d : function d(){},
//}
test(1);//从这里之前创建一个AO对象
全局预编译
① 创建一个GO(global object)对象(GO===window)
② 找形参和变量声明,将变量和形参作为GO属性名,值为undefined
③ 找出函数声明,值为函数体
补充
① imoly、global暗示全局变量:即任何变量。如果变量未经声明就赋值,此变量就归全局变量所有
② 一切声明的全局变量,全是window的属性
全局预编译例子
//1.先创建GO对象
//GO{
//}
//2.找变量声明
//GO{
// a : undefined,
//}
//3.找函数声明
//GO{
// a : undefined,
// demo : function demo(e){}
//}
a = 100;
function demo(e){
function e(){}
arguments[0] = 2;//arguments是实参列表 e变成2
console.log(e); //2
if(a){
var b = 123; //if中定义一个函数声明,语法是不通过的
function c(){}
}
var c;
a = 10;
var a;
console.log(b); //undefined
f = 123; //变量未声明,扔给GO对象
console.log(c); //undefined
console.log(a); //10
}
var a;
demo(1);
//创建AO对象
AO{
e : 2,
b : ,
c : undefined,
a : 10,
}
console.log(a);//100 这个属于全局,所以是100
console.log(f);//123