javascript 的预编译过程
先看一段代码
console.log(a);
var a = 10;
//undefined
打印出来a的值为undefined,这是为什么呢。
因为JavaScript中有预编译,就是我们常说的变量声明提升,函数声明整体提升。
JS 运行三部曲
1、语法解析 (分析是否有语法错误)
2、预编译(全局 和 函数体内)
3、解释运行(除了预编译过的,一行一行运行)
预编译前奏
1、暗示全局变量(任何变量,如果未经声明就赋值,此变量就是全局变量,函数体内也不例外)
例如:a=123; 这个变量a就是全局变量
一切声明的全局变量,全是window的属性
例如:a=123;就等于window.a=123;
预编译(四步曲)
1、创建AO对象
2、找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3、将实参值和形参统一
4、在函数体内找函数声明,值赋给函数体
函数声明 例如: function a () {}
函数结构式 :var b = function (){}
如下
function fn(a) {
console.log(a);
var a =123;
console.log(a);
function a () {}
var b = function () {}
console.log(b);
function d()
console.log(d);
}
fn(1);
预编译发生在函数执行的前一刻。
1、先创建AO对象
AO{
}
2、找形参和变量声明放AO对象中,值为undefined。
代码中只存在a形参和b变量
AO{
a:undefined
b;undefined
}
3、实参形参相统一。
AO{
a:1
b;undefined
}
4、在函数体内找函数声明,值赋给函数体。
AO{
a:function a(){};
b;undefined
d:function d(){}
}
上面那段代码的执行结果为:
function fn(a) {
console.log(a);// AO对象的值为function a(){}
var a = 123;// 变量声明已经在预编译的时候执行的了 在执行时不会执行变量声明 改变Ao对象中属性a值为123
console.log(a); // 123
function a(){}// 这也不执行
console.log(a); // 123
var b = function(){} // vaar b不执行 改变AO对象中的属性b为function(){}
console.log(b);// function() {}
function d(){}// 不执行
console.log(d);//function d () {}
}
fn(1);
全局中的预编译(三部曲)
1、创建GO对象
2、找全局变量声明,将变量作为GO属性名,值为undefined
3、在全局中找函数声明,值赋给函数体
如下
console.log(a);
var a = 123;
function a(){}
1、创建GO对象
GO{
}
2、找到全局中的变量声明,将函数和形参名的作为GO对象的属性名,值为undefined
GO{
a :undefined
}
3、找到全局中函数声明将函数作为GO对象的属性名,值为函数
GO{
a :function a(){}
}
要注意的是,预编译没有赋值(初始化行为),只是发生变量声明和函数声明。匿名函数不参与预编译。
在执行阶段,也就是编译阶段,才会进行变量的赋值(初始化)