预编译
预编译是指在程序运行之前,先对程序进行一些处理,例如预处理、编译、链接等,以便提高程序运行效率和减少运行时的错误。
编译的作用:提高程序的效率和稳定性,减少程序在运行过程中可能出现的错误,并提高程序的可维护性和可扩展性。
作用域
作用域是函数身上的属性 [[scope]](给js引擎访问的,我们拿不到 — 隐式属性),用于存储函数中的有效标识符。
作用域链
作用域是执行期上下文对象的集合,这种集合呈链式连接,我们把这种链关系称之为作用域链。
- GO (Global Object):函数执行上下文对象;
- AO (Activation Object):全局执行上下文对象;(可访问GO)
代码
1function a() {
2 function b(){
3 var b = 22
4 console.log(a)
5 }
6 var a = 111
7 b()
8
9}
10
11var glob = 100
12a()
作用域链
分析
全局定义了函数a和global,形成如图GO,此时a[[scope]]的0指向GO,函数a内定义了函数b和a,形成如图AO,此时a[[scope]]的0指向自己的AO,1指向GO,函数b定义了b,形成如图AO,b[[scope]]的0指向自己的AO,1指向a[[scope]]。
声明提升
- 变量声明,声明提升(上一篇文章提到过)
- 函数声明,整体提升
1test()
2function test() {
3 var a = 123
4 console.log(a)
5}
上述代码相当于:
1
2function test() {
3 var a = 123;
4 console.log(a);
5}
6test();
预编译的分析(重点!)
定义
- 发生在全局:
- 创建GO对象
- 找变量声明,将变量名作为GO的属性名,值为undefined
- 在全局找函数声明,将函数名作为GO的属性名,值为该函数体
- 发生在函数体内:
- 创建一个AO对象
- 找形参和变量声明,将形参和变量名作为AO的属性名,值为undefined
- 形参和实参统一
- 在函数体内找函数声明,将函数名作为AO的属性名,值为该函数体
步骤
全局预编译—>GO—>执行,碰见函数—>函数预编译—>AO—>执行函数
实例一
代码
1var a = 1
2function fn(a) {
3 var a = 2
4 function a() {}
5 console.log(a)
6}
7
8fn(3)
分析
- 首先进行全局预编译—>GO
- GO:{ }
- GO:{ a:undefined }
- GO:{ a:undefined , fn:function(a){ var a = 2; function a() {}; console.log(a); }
- 执行
- GO:{ }
- GO:{ a:1 }
- GO:{ a:undefined , fn:function(a){ var a = 2; function a() {}; console.log(a); }
- 碰见函数,进行函数预编译—>AO
- AO:{ }
- AO:{ a:undefined;(这里是a:undefined;(形参)a:undefined;(变量)) }
- AO:{ a:3(fn(3)), }
- AO:{ a:function(){}, (a:3;a:function(){};最后得出的结果) }
-
执行函数
AO:{ a:2, }
实例二
代码
1function fn() {
2 console.log(a);
3 var a = 123;
4 console.log(a);
5 function a() {};
6 console.log(a);
7 var b = function(){};
8 console.log(b);
9 function c(){};
10 var c = a;
11 console.log(c);
12}
13
14fn(1);
分析
1GO:{
2 fn:function fn(){}
3}
4
5AO:{
6 a:undefined-->undefined-->1-->function a(){}, -->123,
7 b:undefined, -->function b(){},
8 c:undefined-->function c(){}, -->123
9
实例三
代码
1function test(a, b) {
2 console.log(a);
3 c = 0
4 var c;
5 a = 3
6 b = 2
7 console.log(b);
8 function b() {}
9 console.log(b);
10 }
11 test(1)
分析
1GO:{
2 test:function
3}
4
5AO:{
6 a:undefined-->1, -->3
7 b:undefined-->undefined-->function b(){}, -->2
8 c:undefined, -->0
9
10}
个人笔记记录 2021 ~ 2025