js for循環(huán),為什么一定要加var定義i變量
更新時間:2010年06月25日 20:45:20 作者:
我知道,有些人(譬如之前的我)寫js的for循環(huán)時,都不習(xí)慣加上var,這當然是語法允許的。
譬如下面。
for(i=0;i<10;i++){//就不寫成: var i=0
alert(i);
}
但是,這真的不是個好習(xí)慣,下面我就說說為什么寫Js的for循環(huán)一定要加var,否則會時不時給你帶來煩人難查的bug。
譬如現(xiàn)在我們要實現(xiàn)這樣的功能:輸出
10
20
30
40
50
60
70
80
90
100
通過下面code實現(xiàn),WriteNumber從1到10循環(huán),每次循環(huán)調(diào)用TenTimes方法返回10倍的索引值。
<script type="text/javascript">
function WriteNumber() {
for (i = 1; i <= 10; i++) {
document.write(TenTimes(i) + "<br/>")
}
}
function TenTimes(v) {
var result = 0;
alert(i);
for (i = 1; i <= 10; i++) {
result += v;
}
return result;
}
WriteNumber();
//alert(i)
</script>
你會發(fā)現(xiàn)最終只輸出了10。大家可以用下面的代碼框運行測試。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
關(guān)于在WriteNumber和TenTimes方法里加不加var,就是說是否聲明索引變量i有4種情況:
第一種情況,WriteNumber和TenTimes各有1個for循環(huán),2個循環(huán)里均沒有用var聲明i索引變量。
運行結(jié)果:會alert出1。結(jié)果只輸出了10,不是我們所想要的。
分析:執(zhí)行WriteNumber時,其作用域內(nèi)并沒有找到聲明過的變量i,直接對i進行賦值,則隱式的將i聲明為全局變量,(對于函數(shù)內(nèi)部未聲明過的變量,如果給它賦值,會隱式的將它聲明為全局變量。) 循環(huán)開始,i=1,調(diào)TenTimes方法,發(fā)現(xiàn)TenTimes方法也沒有聲明過變量i ,所以TenTimes里的i就是全局變量i,就和WriteNumber的i成了同一個。 這時line9 alert出來的自然是1了。TenTimes循環(huán)了10次,使得全局的i變成了11,自然WriteNumber就不會執(zhí)行第2次循環(huán)操作了。
驗證:如果在WriteNumber();語句后加alert(i),即取消line16的注釋,會發(fā)現(xiàn)alert出12(12=10+2個i++),證明了i此時為windows對象。
第二種情況,WriteNumber聲明了i變量,即line3: var i=1,TenTimes未聲明i變量,即line10: i=1。
運行結(jié)果:line9 alert(i)處報i未定義錯誤 ,因為WriteNumber有聲明過變量i,所以沒有成為全局的i,TenTimes執(zhí)行時又沒有聲明過i,所以報未定義。若注釋掉line9,輸出結(jié)果正確。因為當TenTimes里運行到i=1時,隱式將i聲明是全局變量,不影響WriteNumber里的i。WriteNumber仍然會執(zhí)行10次循環(huán)。
驗證:如果在WriteNumber();語句后加alert(i),即取消line16的注釋,會發(fā)現(xiàn)alert出11(11=10+TenTimes里的i++),證明了此時有windows.i。
第三種情況,WriteNumber沒有聲明i變量,即line3: i=1,TenTimes聲明了i變量,即line10: var i=1。
運行結(jié)果:彈出10個undefined。因為WriteNumber未聲明i,隱式將i聲明是全局變量,而TenTimes有聲明過變量i(補充一句,對于變量的聲明都是在預(yù)編譯中進行的),所以line9 alert(i)里的i不是windows.i,而是TenTimes聲明的變量i,此時當然是undefined了。同時,發(fā)現(xiàn)輸出結(jié)果正確,因為TenTimes的i不會影響WriteNumber的全局i,WriteNumber仍然是執(zhí)行了10次循環(huán)。
第四種情況:WriteNumber和TenTimes均用var聲明了i。
運行結(jié)果:注釋掉line9,不說了,好習(xí)慣,結(jié)果當然完美。
雖然第二、三種情況輸出結(jié)果是正確的,但是對i的使用很混亂,應(yīng)該算是運氣導(dǎo)致結(jié)果正確,因為剛好1個是window.i,一個是函數(shù)內(nèi)部的私有變量i,使得沒有沖突。
此文雖然講的是寫for循環(huán)為什么一定要加var,但其實講的是變量的作用域(或者說變量的生命周期)。理解之后,下面的2段code運行結(jié)果你應(yīng)該能準確說出答案吧。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
Ps:說道coding的好習(xí)慣,想起了這個:if(a==3) 應(yīng)該寫成if(3==a) 。因為我們常會把==寫成1個=,如果把變量寫在右邊時只寫了1個=,就會報編譯錯誤,這樣就能及時發(fā)現(xiàn)錯誤。
復(fù)制代碼 代碼如下:
for(i=0;i<10;i++){//就不寫成: var i=0
alert(i);
}
但是,這真的不是個好習(xí)慣,下面我就說說為什么寫Js的for循環(huán)一定要加var,否則會時不時給你帶來煩人難查的bug。
譬如現(xiàn)在我們要實現(xiàn)這樣的功能:輸出
10
20
30
40
50
60
70
80
90
100
通過下面code實現(xiàn),WriteNumber從1到10循環(huán),每次循環(huán)調(diào)用TenTimes方法返回10倍的索引值。
復(fù)制代碼 代碼如下:
<script type="text/javascript">
function WriteNumber() {
for (i = 1; i <= 10; i++) {
document.write(TenTimes(i) + "<br/>")
}
}
function TenTimes(v) {
var result = 0;
alert(i);
for (i = 1; i <= 10; i++) {
result += v;
}
return result;
}
WriteNumber();
//alert(i)
</script>
你會發(fā)現(xiàn)最終只輸出了10。大家可以用下面的代碼框運行測試。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
關(guān)于在WriteNumber和TenTimes方法里加不加var,就是說是否聲明索引變量i有4種情況:
第一種情況,WriteNumber和TenTimes各有1個for循環(huán),2個循環(huán)里均沒有用var聲明i索引變量。
運行結(jié)果:會alert出1。結(jié)果只輸出了10,不是我們所想要的。
分析:執(zhí)行WriteNumber時,其作用域內(nèi)并沒有找到聲明過的變量i,直接對i進行賦值,則隱式的將i聲明為全局變量,(對于函數(shù)內(nèi)部未聲明過的變量,如果給它賦值,會隱式的將它聲明為全局變量。) 循環(huán)開始,i=1,調(diào)TenTimes方法,發(fā)現(xiàn)TenTimes方法也沒有聲明過變量i ,所以TenTimes里的i就是全局變量i,就和WriteNumber的i成了同一個。 這時line9 alert出來的自然是1了。TenTimes循環(huán)了10次,使得全局的i變成了11,自然WriteNumber就不會執(zhí)行第2次循環(huán)操作了。
驗證:如果在WriteNumber();語句后加alert(i),即取消line16的注釋,會發(fā)現(xiàn)alert出12(12=10+2個i++),證明了i此時為windows對象。
第二種情況,WriteNumber聲明了i變量,即line3: var i=1,TenTimes未聲明i變量,即line10: i=1。
運行結(jié)果:line9 alert(i)處報i未定義錯誤 ,因為WriteNumber有聲明過變量i,所以沒有成為全局的i,TenTimes執(zhí)行時又沒有聲明過i,所以報未定義。若注釋掉line9,輸出結(jié)果正確。因為當TenTimes里運行到i=1時,隱式將i聲明是全局變量,不影響WriteNumber里的i。WriteNumber仍然會執(zhí)行10次循環(huán)。
驗證:如果在WriteNumber();語句后加alert(i),即取消line16的注釋,會發(fā)現(xiàn)alert出11(11=10+TenTimes里的i++),證明了此時有windows.i。
第三種情況,WriteNumber沒有聲明i變量,即line3: i=1,TenTimes聲明了i變量,即line10: var i=1。
運行結(jié)果:彈出10個undefined。因為WriteNumber未聲明i,隱式將i聲明是全局變量,而TenTimes有聲明過變量i(補充一句,對于變量的聲明都是在預(yù)編譯中進行的),所以line9 alert(i)里的i不是windows.i,而是TenTimes聲明的變量i,此時當然是undefined了。同時,發(fā)現(xiàn)輸出結(jié)果正確,因為TenTimes的i不會影響WriteNumber的全局i,WriteNumber仍然是執(zhí)行了10次循環(huán)。
第四種情況:WriteNumber和TenTimes均用var聲明了i。
運行結(jié)果:注釋掉line9,不說了,好習(xí)慣,結(jié)果當然完美。
雖然第二、三種情況輸出結(jié)果是正確的,但是對i的使用很混亂,應(yīng)該算是運氣導(dǎo)致結(jié)果正確,因為剛好1個是window.i,一個是函數(shù)內(nèi)部的私有變量i,使得沒有沖突。
此文雖然講的是寫for循環(huán)為什么一定要加var,但其實講的是變量的作用域(或者說變量的生命周期)。理解之后,下面的2段code運行結(jié)果你應(yīng)該能準確說出答案吧。
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁面才能執(zhí)行]
Ps:說道coding的好習(xí)慣,想起了這個:if(a==3) 應(yīng)該寫成if(3==a) 。因為我們常會把==寫成1個=,如果把變量寫在右邊時只寫了1個=,就會報編譯錯誤,這樣就能及時發(fā)現(xiàn)錯誤。
相關(guān)文章
JavaScript前端中的偽類元素before和after使用詳解
before和after也算是css里面最常見的元素了,而我卻一直不太了解,再不學(xué)一下就真的太不像話了。所以學(xué)習(xí)一下,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-02-02layui默認選中table的CheckBox復(fù)選框方法
今天小編就為大家分享一篇layui默認選中table的CheckBox復(fù)選框方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09淺析JavaScript函數(shù)的調(diào)用模式
這篇文章主要為大家詳細介紹了JavaScript函數(shù)的調(diào)用模式,包括方法調(diào)用模式,構(gòu)造器調(diào)用模式,apply/call調(diào)用模式,感興趣的小伙伴們可以參考一下2016-08-08利用JS如何計算字符串所占字節(jié)數(shù)示例代碼
因為最近項目有個需求要用js計算一串字符串寫入到localStorage里所占的內(nèi)存,所以便有了這篇文章,下面這篇文章主要給大家介紹了關(guān)于利用JS如何計算字符串所占字節(jié)數(shù)的相關(guān)資料,需要的朋友可以參考下。2017-09-09JavaScript實現(xiàn)繼承的7種方式總結(jié)
用官方點的話講繼承是面向?qū)ο笕筇卣髦?,可以使得子類具有父類的屬性和方法,同時還可以在子類中重新定義以及追加屬性和方法。本文整理了JavaScript實現(xiàn)繼承的7種方式,需要的可以了解一下2023-04-04