变量声明提升(hoisting)的概念不太容易描述清楚
先看段代码
var g="global";//全局变量
function foo(){
console.log(g);//想要的预期结果global,而实际上结果是 undefined
var g="local";
console.log(g);//结果为 local
}
foo();
可以看到第一次显示g的时候,没有按我们的预期的显示结果,之所以会这样是因为,所有局部变量的声明都会被提升到最顶层,即上面的代码等效于下面的代码
var g="global";//全局变量
function foo(){
var g; //局部变量,但没赋值 相当于 var g=undefined;
console.log(g);//结果是 undefined
g="local";
console.log(g);//结果为 local
}
foo();
为了避免这样的错误,最好在函数的开始就声明要用的所有变量,并且变量名最好不要与全局变量同名。
再来看看函数的声明提升
function foo(){
console.log("global foo");
}
function boo(){
console.log("global boo");
}
function test(){
console.log(typeof foo);//结果为 function
console.log(typeof boo);//结果为 undefined
foo();//结果为 local foo
boo();//运行出错 TypeError: undefined is not a function
function foo(){
console.log("local foo");
}
var boo=function(){
console.log("local boo");
}
}
test();
根据前面变量声明提升的概念,我们可以清楚为什么boo()会执行报错,因为boo作为一个变量被提升了,运行boo()时,它还只是个undefined的变量,所以运行错误。
但是foo()并没有出错,是因为,变量foo的声明和实现被同时提升了,即上面代码等于下面的
function foo(){
console.log("global foo");
}
function boo(){
console.log("global boo");
}
function test(){
function foo(){
console.log("local foo");
}
var boo;
console.log(typeof foo);//结果为 function
console.log(typeof boo);//结果为 undefined
foo();//结果为 local foo
boo();//运行出错 TypeError: undefined is not a function
boo=function(){
console.log("local boo");
}
}
注意test()函数内的 foo boo的声明方式不一样的
function foo(){}这样的声明可以连同实现体一起被提升
var boo=function(){}这样的方式,只有声明被提升了,实现还是在后面执行