1. 程式人生 > 實用技巧 >JavaScript中for...in迴圈使用問題

JavaScript中for...in迴圈使用問題

問題

使用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]);
}