這個(gè)小小的 for...in 失誤,能把你的代碼庫炸掉
你大概也寫過這一段:
const fruits = ["apple", "banana", "cherry"];
for (let i in fruits) {
console.log(fruits[i]);
}看上去沒毛病,能打印水果。
那為什么大家都說:別在數(shù)組上用 for...in?
因?yàn)樗?/span>表面無害,實(shí)則埋雷——能用,直到某一天不能用。
for...in 的真相
for...in不是為數(shù)組設(shè)計(jì)的,它是用來遍歷對(duì)象的——遍歷可枚舉的屬性鍵:
const person = { name: "Alice", age: 25 };
for (let key in person) {
console.log(key); // name, age
}用于對(duì)象:? 合理。 用于數(shù)組:?? 它依然遍歷“屬性鍵”,不是“索引”。 于是自定義屬性、繼承屬性、非數(shù)字鍵都會(huì)進(jìn)來。
隱藏炸彈一:額外的鍵
const fruits = ["apple", "banana", "cherry"];
fruits.color = "red";
for (let i in fruits) {
console.log(i);
}輸出:
0
1
2
color?? 沒錯(cuò),“color”也進(jìn)循環(huán)了。一旦數(shù)組被加了額外屬性,for...in 就會(huì)照單全收。
隱藏炸彈二:繼承屬性(沉默 Bug)
Array.prototype.custom = "hi";
const arr = [1, 2, 3];
for (let i in arr) {
console.log(i);
}輸出:
0
1
2
custom你可能長(zhǎng)期沒注意……直到某次線上突然炸鍋。
隱藏炸彈三:遍歷順序不保證
for...in 不保證順序。
當(dāng)數(shù)組被當(dāng)作對(duì)象對(duì)待時(shí),順序也不再可靠:
const arr = [10, 20, 30];
arr[100] = 999;
for (let i in arr) {
console.log(i);
}你以為是 0, 1, 2, 100?不同引擎可能給你不同順序——不可預(yù)測(cè)。
正確替代方案 ????
需要遍歷數(shù)組請(qǐng)用下面這些:
1) for...of(遍歷值的首選)
const fruits = ["apple", "banana", "cherry"];
for (let fruit of fruits) {
console.log(fruit);
}→ 語義清晰、順序有保障、現(xiàn)代寫法。
2) 經(jīng)典 for(需要索引或追求極致性能)
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}→ 大數(shù)組下仍然穩(wěn)、快、可控。
3) forEach()(函數(shù)式風(fēng)格)
fruits.forEach(fruit => console.log(fruit));→ 簡(jiǎn)潔、易讀,適合簡(jiǎn)單遍歷。
口決一條(貼在工位)

- ????
for...in→ 對(duì)象(遍歷鍵) - ????
for...of→ 數(shù)組(遍歷值) - ??♀? 別混用
當(dāng)你在數(shù)組上寫下:
for (let i in arr)其實(shí)并不是“遍歷索引”,而是遍歷它“擁有的 + 繼承的”一切屬性。 這就是它不可預(yù)測(cè)、脆弱、偶發(fā)災(zāi)難的根源。
下次看到有人這么寫,立刻攔住他!如果本文幫到你,點(diǎn)個(gè)贊、關(guān)注、留言,讓更多同學(xué)別踩這個(gè)坑。





























