1. 概念解释
在JS预编译中,主要涉及两个概念:AO(Activation Object)和GO(Global Object)
- AO:Activation Object 直译过来就是活跃对象,专业点就是函数执行期上下文,指的是函数的作用域
- GO:Global Object 全局对象,也叫全局上下文,可以简单理解成是JS运行的环境,比如浏览器或者node
2. AO、GO生成步骤
2.1 AO函数执行期上下文
- 寻找形参和函数体的变量声明
- 实参给形参赋值
- 寻找函数体的函数声明
- 执行函数体
function test(a) {
return a;
a = 1;
function a(){}
var a = 2;
}
console.log(test(0)); // function a(){}
1. 寻找形参和函数体的变量声明
AO = {
a: undefined
}
2. 实参给形参赋值
AO = {
a: undefined
0
}
3. 寻找函数体的函数声明
AO = {
a: undefined
0
function a(){}
}
4. 执行函数体
AO = {
a: undefined
0
function a(){}
1 -> 2
}
return a是在a = 1之前,因此返回了function a(){}
2.2 GO 全局上下文
- 寻找变量声明
- 函数声明
- 执行
console.log(a); // undefined
var a = 1;
1. 寻找变量声明
GO = {
a: undefined
}
2. 函数声明
没有函数声明,故GO = { a: undefined }
3. 执行
GO = {
a: undefined
1
}
var a = 1;其实是两个步骤,先声明变量a,然后给a赋值为1,打印a是在赋值之前,因此打印结果为undefined
2.3 AO、GO综合练习
a = 1;
function test(e) {
function e() {}
arguments[0] = 2;
console.log(e); // 2
if (a) {
var b = 3;
}
var c;
a = 4;
var a;
console.log(b); // undefined
f = 5;
console.log(c); // undefined
console.log(a); // 4
}
var a;
test(1);
分析:
在执行该段代码前,JS先进行预编译,生成GO,AO对象
1. 在test被定义前,只有GO
GO = {
a: undefined
test: function test(){}
}
2. 在test执行前,此时有了test的函数上下文AO,f为全局变量,因此f在GO中
AO = {
e: undefined
1
function e() {}
b: undefined
c: undefined
a: undefined
4
}
GO = {
a: undefined
test: function test(){}
f: undefined
}
3. 执行,在执行是发现AO里有a,因此不会找GO里的a,此时a=undefined,因此b = 3不会执行
AO = {
e: undefined
1
function e() {}
2
b: undefined
3
c: undefined
a: undefined
4
}
GO = {
a: undefined
1
test: function test(){}
f: undefined
5
}
最终打印结果:
2
undefined
undefined
4