(for in)遍歷鍵名和 (for of)遍歷鍵值,這種說法嚴謹嗎?
阿新 • • 發佈:2018-12-10
[1] const arr = [7, 8, 9]; const obj = { a: 4, b: 5, c: 6 }; [2] for (let v in arr){ console.log(v); } // 0, 1, 2 [3 ]for (let v in obj){ console.log(v); } // a, b, c [4] arr.child = 'child'; [5] arr.__proto__.getChild = function () { return this.child; }; [6] Array.prototype.parent = 'parent'; [7] for (let v in arr){ console.log(v); } // 0, 1, 2, child, getChild, parent [8]for (let v of arr){ console.log(v); } // 7, 8, 9 [9] for (let v of arr.values()){ console.log(v); } // 7, 8, 9 [10] for (let v of obj){ console.log(v); } // 報錯 [11] typeof arr.keys(); // 'object' arr.keys() instanceof Array; // false arr.keys() instanceof Object; // true
for in
for in在ES5中便出現了。一般用來遍歷物件屬性。但也可用於陣列遍歷,返回的值是陣列的索引,因為,嚴格來說,陣列也是一個物件,所對應的屬性是每個值的索引。 for-in只遍歷物件自身的和繼承的可列舉的屬性(摘自 阮一峰ECMAScript 6 入門-物件擴充套件一章)。如[4]、[5]、[6]所示,為陣列新增可遍歷屬性 (所對應描述器descriptor的enumerable屬性為true) ,在[7]中用for-in遍歷都可遍歷出來。
for of
for of為ES6新增遍歷方法。其可遍歷所有具有 iterator 介面的資料結構。for...of迴圈內部呼叫的是資料結構的Symbol.iterator方法(generator函式)。(摘自 阮一峰ECMAScript 6 入門--Iterator 和 for...of 迴圈一章)
const colorArr = ['red', 'green', 'blue']; for(let v of colorArr) { console.log(v); } // red green blue const colorObj = {}; colorObj[Symbol.iterator] = colorArr[Symbol.iterator].bind(colorArr); for(let v of colorObj) { console.log(v); } // red green blue
總結
所以說,(for in)遍歷鍵名和 (for of)遍歷鍵值,這種說法並不嚴謹。for in確實是遍歷屬性,而且更是遍歷物件自身的和繼承的可列舉的屬性。但是,for of遍歷鍵值這種說法便不嚴謹了,比如說我們一開始在[1]中宣告的物件obj,鍵名為a,b, c; 鍵值為4,5,6;
- 按照(for of)遍歷鍵值這種說法,用for of遍歷obj應該返回鍵值4,5,6。可是如[10]所示,程式執行報錯了。因為物件預設是沒有iterator介面的,我們不可以直接遍歷,當我們需要遍歷物件的屬性時,可以呼叫Object.keys()返回一個數組,用來遍歷所有的鍵名。當我們需要遍歷物件的屬性值時,應該呼叫obj.values()返回一個數組,用來遍歷所有的鍵值。並不是說for-of遍歷鍵值,for-of具體遍歷並返回的是什麼,是視of後面返回的陣列對應是什麼。就obj這個物件來說,我們可以遍歷obj的鍵值(Object.values(obj)),也可以遍歷obj的鍵名(Object.keys(obj)),更可以遍歷物件的obj的鍵值對(Object.entires(obj))。
- 同樣。for-of遍歷陣列,陣列是預設具有iterator介面的,即arr.values(),具體遍歷並返回的是什麼,是視of後面返回的遍歷器物件是什麼。arr的鍵值(arr.values()),也可以遍歷陣列arr的鍵名(arr.keys()),更可以遍歷陣列的arr的鍵值對(arr.entires())。
- 遍歷器物件是一個物件,不是陣列。如[11]所示,arr.keys() 是物件Object的例項,並不是陣列例項。