js for迴圈,為什麼一定要加var定義i變數

2022-01-11 00:22:57 字數 2138 閱讀 9660

我知道,有些人(譬如之前的我)寫js的for迴圈時,都不習慣加上var,這當然是語法允許的。譬如下面。  

for(i=0;i<10;i++)

但是,這真的不是個好習慣,下面我就說說為什麼寫js的for迴圈一定要加var,否則會時不時給你帶來煩人難查的bug。

譬如現在我們要實現這樣的功能:輸出  

1020

3040

5060

7080

90100

通過下面code實現,writenumber從1到10迴圈,每次迴圈呼叫tentimes方法返回10倍的索引值。 

12 functionwritenumber()

6 }7 functiontentimes(v)

13 returnresult;

14 }

15 writenumber();

16 //alert(i)

17 你會發現最終只輸出了10。大家可以用下面的**框執行測試。

關於在writenumber和tentimes方法裡加不加var,就是說是否宣告索引變數i有4種情況:

第一種情況,writenumber和tentimes各有1個for迴圈,2個迴圈裡均沒有用var宣告i索引變數。

執行結果:會alert出1。結果只輸出了10,不是我們所想要的。

分析:執行writenumber時,其作用域內並沒有找到宣告過的變數i,直接對i進行賦值,則隱式的將i宣告為全域性變數,(對於函式內部未宣告過的變數,如果給它賦值,會隱式的將它宣告為全域性變數。

迴圈開始,i=1,調tentimes方法,發現tentimes方法也沒有宣告過變數i ,所以tentimes裡的i就是全域性變數i,就和

writenumber的i成了同乙個。  這時line9

alert出來的自然是1了。tentimes迴圈了10次,使得全域性的i變成了11,自然writenumber就不會執行第2次迴圈操作了。 

驗證:如果在writenumber();語句後加alert(i),即取消line16的注釋,會發現alert出12(12=10+2個i++),證明了i此時為windows物件。

第二種情況,writenumber宣告了i變數,即line3: var i=1,tentimes未宣告i變數,即line10: i=1。

執行結果:line9 alert(i)處報i未定義錯誤

,因為writenumber有宣告過變數i,所以沒有成為全域性的i,tentimes執行時又沒有宣告過i,所以報未定義。若注釋掉line9,輸出結

果正確。因為當tentimes裡執行到i=1時,隱式將i宣告是全域性變數,不影響writenumber裡的i。writenumber仍然會執行10

次迴圈。

驗證:如果在writenumber();語句後加alert(i),即取消line16的注釋,會發現alert出11(11=10+tentimes裡的i++),證明了此時有windows.i。

第三種情況,writenumber沒有宣告i變數,即line3: i=1,tentimes宣告了i變數,即line10: var i=1。

執行結果:彈出10個undefined。因為writenumber未宣告i,隱式將i宣告是全域性變數,而tentimes有宣告過變數

i(補充一句,對於變數的宣告都是在預編譯中進行的),所以line9

alert(i)裡的i不是windows.i,而是tentimes宣告的變數i,此時當然是undefined了。同時,發現輸出結果正確,因為

tentimes的i不會影響writenumber的全域性i,writenumber仍然是執行了10次迴圈。

第四種情況:writenumber和tentimes均用var宣告了i。

執行結果:注釋掉line9,不說了,好習慣,結果當然完美。

雖然第二、三種情況輸出結果是正確的,但是對i的使用很混亂,應該算是運氣導致結果正確,因為剛好1個是window.i,乙個是函式內部的私有變數i,使得沒有衝突。

此文雖然講的是寫for迴圈為什麼一定要加var,但其實講的是變數的作用域(或者說變數的生命週期)。理解之後,下面的2段code執行結果你應該能準確說出答案吧。

ps:說道coding的好習慣,想起了這個:if(a==3) 應該寫成if(3==a) 。因為我們常會把==寫成1個=,如果把變數寫在右邊時只寫了1個=,就會報編譯錯誤,這樣就能及時發現錯誤。

為什麼wait 一定要放在迴圈中

在多執行緒的程式設計實踐中,wait 的使用方法如下 synchronized monitor 處理其他的業務邏輯 那為什麼非要while判斷,而不採用if判斷呢?如下 synchronized monitor 處理其他的業務邏輯 這是因為,如果採用if判斷,當執行緒從wait中喚醒時,那麼將直接執...

Docker 為什麼一定要sudo

這個sudo真是煩死人了,每次都要sudosudo,覺得浪費了我大量的時間。但是,當我學習到如何到如何可以不sudo 為什麼要sudo之後,還是覺得sudo好一些吧,於是最後選擇加乙個環境變數,來節約時間。參考文章中給出了幾個非常高水平的處理辦法,我很喜歡,以後來學。1.如何免sudo實現docke...

為什麼規則一定要簡單?

我們生活在各種各樣的規則中,專案中 企業中 社會中,凡是有人的地方就有規則。規則,不論明規則,還是潛規則,都將約束人們的行為。為什麼規則一定要簡單?只有簡單的規則才能體現公正。試想,玩撲克牌,如果撲克牌的規則過於複雜,複雜到多數玩家無法通曉全部規則,還有誰會玩呢?我們把規則搞複雜的目的是什麼呢?是為...