Javascript中的预编译
预编译在什么时候发生
预编译分为全局预编译和函数预编译:全局预编译发生在页面加载完成时执行,而函数预编译发生在函数执行的前一刻。
全局预编译的步骤
- 创建GO(Global Object,全局执行期上下文,在浏览器中为window)对象;
- 寻找var变量声明,并赋值为undefined;
- 寻找function函数声明,并赋值为函数体;
- 执行代码。
一个小案例
我们先来看一下下面这段代码:
js
var x = 1,
y = z = 0;
function add (n) {
return n = n + 1;
}
y = add(x);
function add (n) {
return n = n + 3;
}
z = add(x)分析
1.创建一个GO对象
js
const OA={
//创建一个OA对象
}2.寻找var变量声明,并赋值为undefined;
js
var x = undefined
var y = undefined
var z = undefined3.寻找function函数声明,并赋值为函数体
js
function add (n) {
return n = n + 1;
} //忽略 因为被下面一个代替了
function add (n) {
return n = n + 3;
}4.执行代码
js
x=1
function add (n) {
return n = n + 3;
}
y = add(x)
z = add(x)
y= 4
z= 4
//所以x=1 y=4 z=4函数预编译的步骤
- 创建AO对象,执行期上下文(后面更新关于执行期上下文详解)。
- 寻找函数的形参和变量声明,将变量和形参名作为AO对象的属性名,值设定为undefined.
- 将形参和实参相统一,即更改形参后的undefined为具体的形参值。
- 寻找函数中的函数声明,将函数名作为AO属性名,值为函数体。
一个小案例
js
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);1.创建OA对象
js
const OA={
}2.寻找函数的形参和变量声明,将变量和形参名作为AO对象的属性名,值设定为undefined.
js
var a=undefined
var b=undefined3.将形参和实参相统一,即更改形参后的undefined为具体的形参值
js
AO{
var a = 1
var b = undefined
}4.寻找函数中的函数声明,将函数名作为AO属性名,值为函数体。
js
AO{
a: function(){}
b: undefined
d: function(){}
}函数开始逐行顺序执行:
js
function fn(a){
console.log(a);// 输出function a(){}
var a = 123;
console.log(a);// 输出123
function a(){};//预编译环节已经进行了变量提升,故执行时不在看这行代码
console.log(a);// 输出123
var b = function(){};//这个是函数表达式不是函数声明,故不能提升,会对AO中的b重新赋值
console.log(b);//输出function(){}
function d(){};
}
指南