ES6以後數據結構除了數組和對象,又添加了Map和Set。遍歷器是一種接口規格,任何數據結構只要部署這個接口,就能夠完成遍歷操做javascript
提供了一個指針,經過指針的指向進行遍歷操做java
它提供了一個指針,默認指向當前數據結構的起始位置。也就是說,遍歷器返回一個內部指針,
第一次調用next方法,將指針指向第一個成員,第二次調用next方法,指針指向第二個成員數組
下面是一個模擬遍歷器指針的例子數據結構
function makeIterator(array) { let nextIndex = 0 return { next: function() { return (nextIndex < array.length) ? {value: array[nextIndex++], done: false} : {value: undefined, done: true} } } } let it = makeIterator(['a', 'b']) it.next() // {value: 'a', done: false} it.next() // {value: 'b', done: false} it.next() // {value: 'undefined', done: false}
遍歷器是一個對象,具備next方法,調用next方法,就能夠遍歷事先給定的數據結構this
Iterator接口的目的,就是爲全部的數據結構提供一種統一的訪問機制,就是for of循環prototype
默認的Iterator接口部署在數據結構的Symbol.iterator
屬性,或者說數據結構具備該屬性就能夠認爲是可遍歷的指針
有三類數據結構原生具有了Iterator接口:數組、類數組對象、Set和Map,能夠直接使用for of方法
而對象須要在Symbol.iterator
的屬性上部署遍歷器方法,才能夠for ofcode
下面是經過遍歷器實現指針結構的例子對象
// 在原型鏈上部署System.iterator方法,調用該方法,會返回遍歷器對象iteator。調用該對象的next方法,在返回一個值的同時,自動將內部指針指向下一個實例 function test (value) { this.value = value this.next = null } test.prototype[Symbol.iterator] = function () { let iterator = { next: next // iterator.next是一個function } let current = this function next () { if (current) { let value = current.value let done = current == null current = current.next return { value: value, done: done } } else { return { done: true } } } return iterator } let one = new test(1), two = new test(2), three = new test(3); one.next = two two.next = three for (let i of one) { console.log(i) // 1 2 3 }
還有一種簡單操做,對於類數組對象接口
NodeList.prototypoe[Symbol.iterator] = Array.prototype[Symbol.iterator]
默認調用iterator接口的場合
部署Symbol.iterator最簡單實現是結合Generator
let myIterable = [] myiIterable[Symbol.iterator] = function* () { yield 1 yield 2 yield 3 } [...myIterable] // [1, 2, 3] // 或者 let obj = { * [Symbol.iterator]() { yield 'hello' yield 'world' } } for (let x of obj) { console.log(x) // hello world }
// 如下狀況報錯 let e = { a: 1, b: 'bbb' } for (let [key, value] of e) { console.log() // error,e is not iterable } // 使用yield包裝一下 function* (obj) { for (let key of Object.keys(obj)) { yield [key, obj[key]] } } for (let [key, value] of entries(obj)) { console.log(key, '->', value) } // a -> 1 // b -> 2 // c -> 3
JavaScript 原有的 for...in 循環,只能得到對象的鍵名,不能直接獲取鍵值。ES6 提供 for...of 循環,容許遍歷得到鍵值。
var arr = ["a", "b", "c", "d"]; for (a in arr) { console.log(a); // 0 1 2 3 } for (a of arr) { console.log(a); // a b c d }