什么是预编译?
预编译发生在函数作用域创建的阶段在函数执行之前。
函数、形参、变量的优先级别:
函数 > 形参 > 变量
全局作用域预编译
- 创建GO对象(Global Object)
- 查找变量声明,将变量名作为GO对象的属性名,只为 undefined
- 查找函数声明,值为函数体
函数作用域预编译
- 创建AO对象(Active Object)
- 查找函数形参以及函数内部的变量声明,形参名及变量名作为AO对象的属性,值为 undefined
- 实参和形参相统一,实参值赋给形参
- 查找函数声明,函数名作为AO对象的属性,如果函数名称和变量名称相同时会覆盖变量声明
1 | function fn(a){
|
2 | console.log(a,1);
|
3 | var a = 2222;
|
4 | console.log(a,2);
|
5 | function a () {}
|
6 | console.log(a,3);
|
7 | }
|
8 | fn(1,2)
|
示例
1 | function fn(a, c) {
|
2 | console.log(a);
|
3 | var a = 123;
|
4 | console.log(a);
|
5 | console.log(c);
|
6 | function a() { }
|
7 | if (false) {
|
8 | var d = 678
|
9 | }
|
10 | console.log(d);
|
11 | console.log(b);
|
12 | var b = function () { }
|
13 | console.log(b);
|
14 | function c() { }
|
15 | console.log(c);
|
16 | }
|
17 |
|
18 | fn(1, 2)
|
第一阶段:创建 AO 对象,查找函数形参以及函数内部的变量声明,实参和形参相统一,如果没有传递实参,那么值为 undefined
1 | AO : {
|
2 | a : undefined -> 1
|
3 | c : undefined -> 2
|
4 | b : undefined
|
5 | d : undefined
|
6 | }
|
第二阶段:查找函数声明
1 | AO : {
|
2 | a : undefined -> 1 -> function a() { }
|
3 | c : undefined -> 2 -> function c() { }
|
4 | b : undefined -> function () { }
|
5 | d : undefined
|
6 | }
|
执行代码
1 | function fn(a, c) {
|
2 | console.log(a);
|
3 | var a = 123;
|
4 | console.log(a);
|
5 | console.log(c);
|
6 | function a() { }
|
7 | if (false) {
|
8 | var d = 678
|
9 | }
|
10 | console.log(d);
|
11 | console.log(b);
|
12 | var b = function () { }
|
13 | console.log(b);
|
14 | function c() { }
|
15 | console.log(c);
|
16 | }
|
17 |
|
18 | fn(1, 2)
|