变量提拔:变量的声明写在能够在运用变量以后;
函数提拔:函数能够先挪用,后声明;
上面先诠释了下我明白的这两个观点的定义。要真正明白它们,最好从变量对象的角度动身。引出变量对象的观点,要先明白实行高低文,也就是当控制器实行到可实行代码的时刻,就会天生一个实行高低文,也就是代码的实行环境,会发生一个作用域。这个实行高低文的生命周期有两个阶段:竖立阶段 和 代码实行阶段
竖立阶段就会竖立变量对象,竖立的历程分三步:
1.竖立arguments对象。搜检当前高低文中的参数,竖立该对象下的属性与属性值
2.先搜检有无函数声明(应用function关键字声明的函数,在变量对象顶用函数名作为属性名,属性值是函数内存地点
的援用。假如函数名的援用已存在,那末会被新的援用掩盖)
3.再搜检变量声明,每找到一个变量声明,就在变量对象里用变量名作为属性名,属性值是undefined。假如变量名已存在,直接跳过,目标是防备把同名的函数被修改成undefined
实行阶段会将变量对象转换为运动对象:
竖立完成以后,就会最先实行代码,这个时刻,会完成变量赋值,函数援用,以及实行其他代码。
(在变量对象竖立历程当中,个中的属性不可接见。只要在实行阶段转为运动对象后,才能够接见个中的内容)
先来一个简朴的例子:
function foo(){
a = 2;
function a(){
console.log("函数")
}
console.log(a); //2
var a;
};
foo();
这个例子中,当控制器碰到这段代码时刻,会构成一个实行高低文。随后进入到实行高低文的第一个生命周期:竖立阶段,此时,实行竖立变量对象的三个步骤。
- 因为没有参数。直接进入第二步。
- 起首搜检高低文中有无function关键字声明的函数,以a为属性名,函数的援用为属性值,添加到变量对象中。
- 再搜检函数声明,发现了变量名a,然则,以a为属性名的属性值已存在,所以跳过。
接下来进入第二个生命周期:代码实行
a被赋值为2,函数a未被挪用。打印a即是2
函数提拔也是一个原理,因为变量对象竖立历程当中会先搜检function关键字声明的函数,以该函数的函数名为属性,值为函数地点的援用,添加进变量对象中。