一. 预编译
预编译发生在函数执行的前一刻
全局下面:
- 声明的全局变量和函数会存放在全局对象内(Global Object,简称GO,也属于window的一部分,可直接理解成window对象)。
函数里面:
- 预编译会提前将函数里的变量声明和函数声明依据规则存放在其活动对象内(Activation Object,简称AO(函数作用域对象))。
1.js三步骤
- 首要先做语法分析,若有明显的低级错误语法,就直接报错,所有代码均不执行;
- 预编译;
- 解释执行:解释一行,执行一行。
2.函数中的预编译执行步骤
函数执行的前一刻发生预编译
Step1:创建AO对象,执行期上下文;
Step2:找到形参和变量声明,将形参和变量声明放到AO对象里,且值为undefined;
Step3:形参和实参相统一,就是更改形参后的undefined为具体的形参值;
Step4:找函数里面的函数声明,值为函数体;
代码演示
function fn (a, b, c) {
console.log(c);
function c() {}
var a = function () {}//函数表达式
b = 100;
var b;
console.log(b);
console.log(a);
console.log(c);
}
fn(2, 6);
演示一下执行步骤的详细分析过程
- Step1:创建AO对象,执行期上下文;
AO{
//空对象
}
-Step2:找到形参和变量声明,将形参和变量声明放到AO对象里,且值为undefined;
AO{
a:undefined,
b:undefined,
c:undefined
}
- Step3:形参和实参相统一,就是更改形参后的undefined为具体的形参值;
AO{
a:2,
b:100,
c:undefined
}
- Step4:找函数里面的函数声明,值为函数体;
AO{
a:function () {},
b:100,
c:function c () {}
}
函数执行完成,AO对象就会被销毁。
全局中的预编译
全局当中的预编译与函数中的预编译相似,第一步就是创建GO对象,第二步找到变量声明,与函数中的预编译不同之处,在于没有形参与实参的相统一。
暗示全局变量
来看实例:
function fn () {
var a = b = 999;
console.log(window.a);//undefined
console.log(window.b)//999
}
实例中变量b未声明就被赋值了999,所以属于window。
二.作用域链
function f1(){
function f2 (){
function f3 (){
}
f3();
}
f2();
}
f1();
数定义的时候产生GO,函数执行前产生GO,作用域链如下
如有错误请指出,谢谢