變量提升的問題hoisting
1.先看一段代碼
var a="you bad bad";
alert(v);
可以預(yù)見的結(jié)果是輸出you bad bad
2.修改一下
var a="you bad bad";
(function(){
alert(a);})()
彈出的結(jié)果是一樣的
3.但是接下來
var a="you bad bad";
(function(){
alert(a);
var a=" I love you";
})()
這個會彈出什么呢?
這里拋出了一個undefined。這里面就是一個變量提升的問題。
變量提升顧名思義就是把下面的變量或函數(shù)提到程序上面去定義,為了解釋提升,我們先看一下js的作用域問題(scoping)。
1.在我們熟悉的C語言中
inta =1;
printf("%d, ", b);// 1
if(true) {
inta =2;
printf("%d, ", a);// 2
}
printf("%d\n", a;// 1
輸出的結(jié)果將是1,2,1,這是因為在c語言中有塊級作用域的概念,在if塊中聲明的變量,不會影響到外部作用域。
2.JavaScript中就不是上面的情況了
var a=1;
console.log(a);//1
if(true)
{
var a=2;
console.log(a);//2
}
console.log(a);//2
在這里輸出結(jié)果是1,2,2.這是尹js中是函數(shù)級作用域。只有函數(shù)才會創(chuàng)建出新的作用域。
為了解決上面的問題,我么可以這樣寫
functionfoo(){
vara=1;
if(true){
(function(){
vara=2;
}());
}
console.log(a);//1
}
這樣就是可以創(chuàng)建一個域不影響其他變量。
3.變量提升的時候只是提升變量的聲明,并不會把賦值也提升。
看這個例子
(function(){
vara='apple;
varb='pear';
varc='banana';)
實際上,它的過程是
(function(){
vara,b,c;
a='apple';
b='pear';
c='banana';
})()
所以我們最開始那段報出undefined的代碼應(yīng)該是這樣的
vara="you bad bad";
(function(){
vara;
alert(a);
vara=" I love you";
})()
從這里我們可以知道,我們主要把變量放在塊級作用域的頂端,即var a;防止出現(xiàn)不希望看見的結(jié)果。
4.剛剛說不僅變量可以提升,函數(shù)也可以提升。我們知道在js中,函數(shù)有兩種寫法,一中是函數(shù)表達(dá)式,一種是函數(shù)聲明方式,而只有函數(shù)聲明方式才能被提升。
函數(shù)表達(dá)式失敗提升:
functionMy(){
foo();
varfoo=functionfoo(){
alert("you bad bad");
}
}
My();
函數(shù)聲明提升成功:
functionMy(){
foo();
functionfoo(){
alert("you bad bad");
}
}
My();