遇到了JS的变量声明提升,英文名为Hosting,具体来讲是指JS在对当前作用域中的声明代码,会将其提升至当前作用域的最顶端。本文通过几个示例来详细理解一下:
示例一
1
2
3
4
5
var myvar = 'my value' ;
( function () {
alert ( myvar );
})();
这种情况下,在浏览器中执行,会看到 my value
的提示框。
1
2
3
4
5
6
var myvar = 'my value' ;
( function () {
alert ( myvar );
var myvar = 'local value' ;
})();
这时,我们确得到的输出资料是 undefined
。并不是全局的 myvar,这就是因为在function的作用域内,将变量myvar
的声明提升至 alert
的上方,等同于下面的代码:
1
2
3
4
5
6
7
var myvar = 'my value' ;
( function () {
var myvar ;
alert ( myvar );
myvar = 'local value' ;
})();
示例二
1
2
3
4
5
6
( function (){
newFuntion ();
var newFuntion = function (){
alert ( "hello word" );
}
})();
这段代码将不会有任何输出,但会得到一个错误信息,Uncaught TypeError: newFuntion is not a function
。可以看出,其也会对函数的变量声明也会进行提升,等同于这段代码:
1
2
3
4
5
6
7
( function (){
var newFuntion ;
newFuntion ();
newFuntion = function (){
alert ( "hello word" );
}
})();
但是,这样调用就不会出错:
1
2
3
4
5
6
( function (){
newFuntion ();
function newFuntion (){
alert ( "hello word" );
}
})();
这是函数声明的写法,会优先在当前作用域进行函数的注册,所以调用的时候,函数已经存在,没有问题。
示例三
1
2
3
4
5
6
7
8
var a = 1 ;
function b () {
a = 10 ;
return ;
function a () {}
}
b ();
alert ( a );
这个示例的输出,给我们的结果是个"1"的弹出框,很困惑了有木有?对代码改动一下,
1
2
3
4
5
6
7
8
var a = 1 ;
function b () {
alert ( a );
a = 10 ;
return ;
function a () {}
}
b ();
得到的a 是function a(){}
。得到的结果是其对函数的声明。需要注意的是,这里在function b下面的a因为函数声明的问题,已经变为了一个局部变量,所以不会影响全局变量a,所以之前代码的结果输出为1,也就很容易理解了。
总结
变量声明的时候,变量赋值并没有被提升,只是声明被提升了。但是,同时要注意函数声明与函数表达式的区别: 函数声明会在当前作用域优先进行注册,会产生覆盖的效果,而函数表达式则是按代码顺序进行执行 。所以下面这段也就容易理解了:
1
2
3
4
5
6
7
8
9
10
11
function test () {
foo (); // TypeError "foo is not a function"
bar (); // "this will run!"
var foo = function () { // 变量指向函数表达式
alert ( "this won't run!" );
}
function bar () { // 函数声明 函数名为bar
alert ( "this will run!" );
}
}
test ();
参考资料