讲述这个概念之前,我们首先来看一个简单的例子:
console.log(a);
var a=100;
console.log(a);
当你在思考各会输出什么值的时候,你其实进入了变量申明提前的概念中了。
①var声明提前
概念:变量在声明它们的脚本或函数中都是有定义的,变量声明语句会被提前到脚本或函数的顶部。但是,变量初始化的操作还是在原来var语句的位置执行,在声明语句之前变量的值是undefined。
总结出三个简单的点:
1.变量声明会提前到函数的顶部;
2.只是声明被提前,初始化不提前,初始化还在原来初始化的位置进行初始化;
3.在声明之前变量的值是undefined。
回到刚刚的例子,由于声明提前,所以代码会变成这样
var a; //声明提前
console.log(a); //undefined
a=100; //赋值任然留在原位置
console.log(a); //100
大家理解了var 声明提前了,再来看看这个例子:
var a=123;
function a()
{
return 1 ;
}
console.log(a);
你会发现这个好像和之前说的var声明提前又有不同的范畴了,对的,我们进入函数声明提前的概念。
②函数声明提前
概念:函数申明提前的原理与变量申明提前情况类似,需要提醒的是,只有函数申明格式的函数才会存在函数申明提前,比如函数表达式,构造函数,都不存在函数申明提前。
回到刚刚的例子,由于函数声明提前,所以代码会变成这样
var a;
function a()
{
return 1
}
a=123;
console.log(a); //123
大家理解了函数声明提前的概念了,那大家看看这一题:
console.log(a);
var a = "孙悟空";
function a(){ console.log("小钻风"); }
这里就有个问题了,函数申明提前,变量申明也提前,到底谁会更提的更前?假设两者都用的同一命名申明,到底最后会输出啥?
③var变量、函数声明提前的顺序
概念:同一作用域下var 变量、函数声明提前同时存在时,函数会首先被提升,然后才是变量。
所以刚刚的代码回顾下,等同于:
function a(){
console.log("小钻风");
}
var a;//由于上面函数已申明a,相同的变量名申明会被直接忽略
console.log(a);//输出函数本体
a = "孙悟空";
这里有个问题不知道小伙伴注意到没有,函数提前后,又var a了一次,为啥不输出undefined?
因为这里只是再次申明a,并未修改现有a的值
做个简单的测试:
var a=1;
var a;
console.log(a);//1
变量a已经申明过了,而且也赋值了,后面再次申明只是申明并未修改值,这种申明方式会被直接忽略,所以还是输出1.