iT邦幫忙

0

for 迴圈問題

for(var i = 1; i <= 5; i++) {
setTimeout(function() {
console.log(i)
}, i)
}
console.log(i)

請問如果是i <= 5; 那為什麼++之後結果是6呢?

看更多先前的討論...收起先前的討論...
咖咖拉 iT邦研究生 4 級 ‧ 2021-04-07 17:59:42 檢舉
for(var i = 1; i < 5; i++) {
setTimeout(function() {
console.log(i)
}, i)
}
console.log(i)

#5
感謝你的回覆
推薦你
https://ithelp.ithome.com.tw/users/20065504/ironman/1259
我剛看完 受益良多
當5是執行最後一次,到6時超出<=5的範圍才結束迴圈
3
koro_michael
iT邦新手 4 級 ‧ 2021-04-07 18:00:14
最佳解答

for(初始化; 限制條件; 每次執行完畢的調用)

順序 初始化 -> 限制條件 -> 調用

i <= 5 的限制條件執行後還會跑一次 i++

所以結果是 6

如果你想要看到 1 - 5,建議你改成這樣

for(var i = 1; i <= 5; i++) {
	const _i = i;
	setTimeout(() => {
		console.log(_i);
	}, i);
}
看更多先前的回應...收起先前的回應...
通靈亡 iT邦研究生 3 級 ‧ 2021-04-07 20:31:25 檢舉

其實將 var 直接改成 let 就可以了,不需要額外用 const 接外面的 var。

https://jsfiddle.net/c0p36unh/

for (let i = 1; i <= 5; i++) {
  setTimeout(function () {
    console.log(i)
  }, i)
}
小魚 iT邦大師 1 級 ‧ 2021-04-07 20:46:20 檢舉

他應該是在學習中,
多嘗試也不是壞事.

懂了,謝謝~~~~

通靈亡這樣又要解釋let var的差異以及為什麼改一下宣告方式就可以了(我覺得好麻煩),乾脆先讓樓主知道他原本的用法有什麼問題,以及最直覺的改善方式

而且雖然靠 let 可以讓 i 的作用域只停留在 for 迴圈裡面,但是在迴圈中修改 i 的值依然會讓 settimeout 中的值有變化,這樣無形中還是會有機會埋下奇怪的 bug,所以寫法還是宣告成 const 比較好一點

for (let i = 1; i <= 5; i++) {
  setTimeout(() => {
    console.log(i)
  }, i);
  
  i += 1;
}
通靈亡 iT邦研究生 3 級 ‧ 2021-04-09 00:54:23 檢舉

這樣又要解釋let var的差異以及為什麼改一下宣告方式就可以了(我覺得好麻煩)

了解。

但是在迴圈中修改 i 的值依然會讓 settimeout 中的值有變化,這樣無形中還是會有機會埋下奇怪的 bug

對新手來說,作用域、非同步的基礎不熟,加上不清楚自己寫下每一行程式碼的用意,怎麼寫都會容易埋下 bug。

通靈亡 新手總是得走過那些自己造出來的坑才行~

教給他嚴謹的寫作風格,能幫新手減少一個坑是一個(雖然可能沒啥用)

0
Homura
iT邦高手 1 級 ‧ 2021-04-07 17:58:37

因為6才會結束for迴圈啊...
然後settimout在倒數完前就跑完for迴圈了
我應該沒理解錯吧?XD

settimout 跑出來的所有結果應該都是 6 /images/emoticon/emoticon01.gif

Homura iT邦高手 1 級 ‧ 2021-04-07 18:07:37 檢舉

koro_michael
是啊
我有說輸出前就跑完了啊0.0

懂了,意思是i>5也就是6的時候迴圈會停止

2
小魚
iT邦大師 1 級 ‧ 2021-04-07 18:04:08

因為i=6的時候不合條件,
所以就不會執行迴圈內的內容,
不過setTimeout用在這裡好像...

setTimeout用FOR來跑,一定會死人。

通靈亡 iT邦研究生 3 級 ‧ 2021-04-07 21:51:05 檢舉

感覺是在準備面試的樣子,大部分看起來比較奇怪的程式碼在面試題目當中常常看到
https://ithelp.ithome.com.tw/articles/10220329

對~~~ 沒想到好多基礎的不懂

2

for的解釋如下

for(起始設定值; 判斷式; 累進值)

也就是說,就流程來說。

(起始)->(判斷)->處理回圈內程式->(累進)->(判斷)->--成功--回圈程式->(累進)->(判斷)......失敗

所以最後的I值一定是6。
因為它累進到6後,判斷式才會不成立,才會跳出來。

這樣是否了解了。

起始後會先判斷,再決定要不要執行

for (let i = 1; i < 1; i++) {
	alert(i);
}

了解了~就是會先判斷,感謝

我要發表回答

立即登入回答