先說結論
JavaScript 中, 強烈建議聲明變量時使用 var.
不使用 var 似乎也可以聲明變量, 但是本質上是有區(qū)別的:
- 帶
var表示"在當前作用域下聲明變量, 并且賦值"; - 不帶
var則會冒泡尋找(由內往外尋找)需要賦值的對象, 從而會污染全局變量;
PS. 如果要了解本質原因, 可以參考 <<代碼之髓>> 的第 7 章:
本質原因是 JavaScript 把用var聲明的變量視為"靜態(tài)作用域", 而把沒有任何聲明的變量視為"全局作用域".
試驗 01 -- 用var聲明變量
window.str = 'GuangDong';
function t1(){
var str = 'GuangZhou';
function t2(){
var str = 'FoShan';
alert(str);
}
t2();
}
t1();
alert(window.str);
輸出結果:
FoShan
GuangDong
試驗 02 -- 冒泡尋找
window.str = 'GuangDong';
function t1(){
var str = 'GuangZhou';
function t2(){
alert(str);
}
t2();
}
t1();
alert(window.str);
輸出結果:
GuangZhou
GuangDong
分析:
t2()函數里面的str變量沒用var, 所以只是"賦值", 會往外冒泡尋找需要賦值的變量.
發(fā)現t1()函數的var str = 'GuangZhou', 所以alert('GuangZhou')
做為對比, PHP如果沒有聲明str, 會報錯:
$str = 'GuangDong';
function t1(){
$str = 'GuangZhou';
function t2(){
echo $str;
}
t2();
}
t1();
這個PHP的demo會報錯:
PHP Notice: Undefined variable
試驗 03 -- 冒泡尋找
window.str = 'GuangDong';
function t1(){
function t2(){
alert(str);
}
t2();
}
t1();
alert(window.str);
輸出結果:
GuangDong
GuangDong
分析:
alert(str)在t2()內部找不到str變量, 冒泡往外尋找,
在t1()也找不到str變量, 繼續(xù)冒泡往外尋找,
發(fā)現全局變量window.str,
所以輸出GuangDong.
試驗 04 -- 全局變量被污染
window.str = 'GuangDong';
function t1(){
function t2(){
str = 'FoShan';
alert(str);
}
t2();
}
t1();
alert(window.str);
輸出結果:
FoShan
FoShan
分析:
t2()里面的str變量沒有使用var, 所以會冒泡往外尋找, 一直找到window.str, 將其賦值為FoShan.
所以輸出全局變量alert(window.str)時, 輸出FoShan.
參考文章
- <<代碼之髓>> 第 7 章 -- 名字和作用域
文章歷史
- 2016/12/21 (第一次發(fā)布);
- 2017/07/13 引用了<<代碼之髓>>;
如果你覺得我的文章對你有用, 希望能給些改進的建議或者打個"喜歡" _