3 回答

TA貢獻(xiàn)1801條經(jīng)驗(yàn) 獲得超8個(gè)贊
不要for..in用于數(shù)組迭代。
重要的是要理解,[]用于訪(fǎng)問(wèn)索引的Javascript數(shù)組的方括號(hào)語(yǔ)法()實(shí)際上是從Object... 繼承的。
obj.prop === obj['prop'] // true
該for..in結(jié)構(gòu)不能像for..each/in其他語(yǔ)言(php,python等)中所看到的那樣更傳統(tǒng)。
Javascript for..in旨在迭代對(duì)象的屬性。產(chǎn)生每個(gè)屬性的密鑰。結(jié)合使用該鍵和Object的方括號(hào)語(yǔ)法,您可以輕松訪(fǎng)問(wèn)所需的值。
var obj = {
foo: "bar",
fizz: "buzz",
moo: "muck"
};
for ( var prop in obj ) {
console.log(prop); // foo / fizz / moo
console.log(obj[prop]); // bar / buzz / muck
}
并且由于數(shù)組只是具有順序數(shù)字屬性名稱(chēng)(索引)的對(duì)象,因此其for..in工作方式類(lèi)似,因此產(chǎn)生數(shù)字索引的方式與生成上面的屬性名稱(chēng)的方式相同。
該for..in結(jié)構(gòu)的一個(gè)重要特征是,它將繼續(xù)在原型鏈中尋找可枚舉的屬性。它還將迭代繼承的可枚舉屬性。您有責(zé)任驗(yàn)證當(dāng)前屬性是否直接存在于本地對(duì)象上,而不是它所附加的原型是否存在于本地對(duì)象上hasOwnProperty()。
for ( var prop in obj ) {
if ( obj.hasOwnProperty(prop) ) {
// prop is actually obj's property (not inherited)
}
}
(有關(guān)原型繼承的更多信息)
for..in在A(yíng)rray類(lèi)型上使用結(jié)構(gòu)的問(wèn)題在于,無(wú)法保證生成屬性的順序...而且通常來(lái)說(shuō),這是處理數(shù)組時(shí)極為重要的功能。
另一個(gè)問(wèn)題是它通常比標(biāo)準(zhǔn)for實(shí)現(xiàn)慢。
底線(xiàn)
使用a for...in來(lái)迭代數(shù)組就像使用螺絲刀的but子釘釘子一樣...為什么不只使用錘子(for)?

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超4個(gè)贊
for...in當(dāng)您要遍歷對(duì)象的屬性時(shí)使用。但是它的作用與普通for循環(huán)相同:循環(huán)變量包含當(dāng)前的“索引”,表示對(duì)象的屬性而不是值。
要遍歷數(shù)組,應(yīng)使用常規(guī)for循環(huán)。buttons不是一個(gè)數(shù)組,而是一個(gè)NodeList(類(lèi)似數(shù)組的結(jié)構(gòu))。
如果迭代buttons與for...in具有:
for(var i in a) {
console.log(i)
}
您將看到它輸出如下內(nèi)容:
1
2
...
length
item
因?yàn)閘ength和item是類(lèi)型的對(duì)象的兩個(gè)屬性NodeList。因此,如果您天真地使用for..in,您將嘗試訪(fǎng)問(wèn)buttons['length'].removeAttribute(),這將引發(fā)錯(cuò)誤,因?yàn)閎uttons['length']它是函數(shù)而不是DOM元素。
因此正確的方法是使用普通for循環(huán)。但是還有另一個(gè)問(wèn)題:
NodeLists處于活動(dòng)狀態(tài),這意味著每當(dāng)您訪(fǎng)問(wèn)時(shí)length,列表便會(huì)更新(再次搜索元素)。因此,您應(yīng)該避免不必要的呼叫l(wèi)ength。
例:
for(var i = 0, l = buttons.length; i < l, i++)

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超13個(gè)贊
盡管for..in通常不應(yīng)用于數(shù)組,但是在ES5之前,有一種將其與稀疏數(shù)組一起使用的情況。
如其他答案所述,for..in和Arrays的主要問(wèn)題是:
屬性不一定按順序返回(即不是0、1、2等)。
返回所有可枚舉的屬性,包括非索引屬性和[[Prototype]]鏈上的那些屬性。這可能導(dǎo)致性能降低,因?yàn)榭赡苄枰猦asOwnProperty測(cè)試來(lái)避免繼承屬性。
在ES5之前使用..的原因之一是使用稀疏數(shù)組可以提高性能,前提是順序無(wú)關(guān)緊要。例如,在下面:
var a = [0];
a[1000] = 1;
遍歷一個(gè)使用for..in會(huì)比使用for循環(huán),因?yàn)樗粌H可以訪(fǎng)問(wèn)兩個(gè)屬性,而一個(gè)for循環(huán)將嘗試1001快得多。
但是,ES5的forEach使得這種情況變得多余,它僅訪(fǎng)問(wèn)現(xiàn)有的成員,因此:
a.forEach();
還將僅依次迭代兩個(gè)屬性。
添加回答
舉報(bào)