JavaScript中for...in迴圈使用問題
阿新 • • 發佈:2020-11-04
問題
使用for...in去遍歷一個數組,同時將值新增到另外一個數組時,新的陣列中每次都多出來一個function型別的元素。
原因及解決方案
for...in用來迴圈本身沒有問題,但是經常被誤用來遍歷陣列或者類似資料的物件。
for...in的本意是用來遍歷物件的屬性,這就會導致遍歷時上升到原型鏈的層次,不僅會遍歷自身的屬性,還會遍歷繼承獲得的屬性,然而有時這是不需要的。
另外,即使確定要遍歷的陣列沒有繼承屬性,在使用for...in進行遍歷時,並不能保證獲取的元素順序和陣列中原始順序一致。
例如在JScript (IE <= 8)
中,遍歷陣列的順序是元素加入陣列的順序
var array = []; array[2] = 'c'; array[1] = 'b'; array[0] = 'a'; for (var p in array) { //... p will be "2", "1" and "0" on IE }
另外,對於繼承屬性,如果你擴充套件了Array.prototype
物件,這個擴充套件屬性也會被遍歷出來
Array.prototype.last = function () { return this[this.length-1]; };
for (var p in []) { // an empty array
// last will be enumerated
}
使用for...in遍歷一個物件的屬性時,如果只想遍歷物件本身的屬性,那麼可以使用hasOwnProperty
方法進行判斷
for (var prop in obj) { if (obj.hasOwnProperty(prop)) { // prop is not inherited } }
如果要遍歷一個數組或者一個類似陣列的物件,最好是使用一個順序迴圈,例如一個普通的for/while迴圈,也可以使用ES6中的for...of迴圈。
for...of迴圈例子:
//迴圈一個數組 let iterable = [10, 20, 30]; for (let value of iterable) { console.log(value); } //迴圈一個字串 let iterable = "boo"; for (let value of iterable) { console.log(value); } //迴圈一個map let iterable = new Map([["a", 1], ["b", 2], ["c", 3]]); for (let [key, value] of iterable) { console.log(value); } //或者 for (let entry of iterable) { console.log(entry); } //迴圈一個擁有enumerable屬性的物件 for (var key of Object.keys(someObject)) { console.log(key + ": " + someObject[key]); }