例:
function a(b) {
var b=2;
console.log(b);
function b() {
console.log(b);
}
b();
}
a(1);
function a(b) {
console.log(b);
function b() {
console.log(b);
}
b();
}
a(1);
两个函数分别得出什么样的结果?
一.分析过程:
0:形成AO = {} 函数运行前的一瞬间,生成Active Object (活动对象),下称AO;
1:
- 1.1 分析形参 AO = {b:undefined}
- 1.2 接收实参 AO = {b:1}
2:分析变量声明!如var b
-
如果AO上还没有b属性,则添加AO属性,值是undefinded
-
如果AO上已经有b属性,则不作任何影响
3:分析函数声明,如 function b(){},
-
则把函数赋值给AO.b属性,
注:如果此前b属性已存在,则被无情覆盖了
二.执行过程:
执行上下文栈
创建执行上下文的过程
创建变量对象
-
创建 arguments 对象:创建 arguments 对象,该对象中包含实参,此过程仅在函数(非箭头函数)中进行。
-
函数声明提升:每发现一个函数声明,在变量对象中创建与函数名相同的属性,值是指向这个函数的指针,如果这个函数名已存在,则重写这个指针的值。
-
变量声明提升:每发现一个变量声明,在变量对象中创建与变量名相同的属性,值初始化为undefined,如果变量名已存在,则什么也不做。
例如上题
第一个
词法分析过程
AO{b:undefined}
AO{b:1}
AO{b:function b(){}}
执行过程
AO{b:2} b被赋值2 赋值操作是在执行阶段!
console.log(b) //2
function b(){
console.log(b);
}
b();//2
第二个
词法分析过程
AO{b:undefined}
AO{b:1}
AO{b:function b(){}}
执行过程
console.log(b); //function b() {console.log(b);}
function b() {
console.log(b);
}
b(); //function b() {console.log(b);}