文章目錄
- 前言
- 實現原理:
- 調用迭代器
- 自制迭代器
前言
迭代器是 JSt 中一種特殊的對象,它提供了一種統一的、通用的方式遍歷個各種不同類型的數據結構。
可以遍歷的數據結構包括:數組、字符串、Set、Map 等可迭代對象。我們也可以自定義實現迭代器,以支持遍歷自定義的數據結構。
實現原理:
迭代器的實現原理是通過定義一個特定的next() 方法,在每次迭代中返回一個包含兩個屬性的對象:done
和 value
。
next()方法
- 參數:無參數或者有一個參數。
- 返回值:返回一個有兩個屬性的對象。屬性值如下:
done
:布爾值,表示迭代是否完成
value
:當前步驟的值
每次調用next方法,都會改變value值至下一步,直到迭代完成
據此,可以給數組手寫一個迭代器函數
const strArr = ['a', 'b', 'c', 'd'];// 為數組封裝迭代器
function create(arr) {let index = 0;return {next: () => {if (index < arr.length) {return { done: false, value: arr[index++] };} else {return { done: true };}},};
}const str = create(strArr);
console.log(JSON.stringify(str.next()));
console.log(JSON.stringify(str.next()));
console.log(JSON.stringify(str.next()));
console.log(JSON.stringify(str.next()));
console.log(JSON.stringify(str.next()));
//輸出
// {"done":false,"value":"a"}
// 測試.html:28 {"done":false,"value":"b"}
// 測試.html:29 {"done":false,"value":"c"}
// 測試.html:30 {"done":false,"value":"d"}
// 測試.html:31 {"done":true}
可以看到 ,每調用一次next,value會向后移動,直至遍歷完畢
調用迭代器
語法
const a=可迭代對象[Symbol.iterator]()
實例如下
const myArr = ['a', 'b', 'c', 'd'];// 獲取數組自帶的迭代器對象
const myIterator = myArr[Symbol.iterator]();// 通過迭代器的 next() 方法遍歷數組
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
//輸出
// {"value":"a","done":false}
// 測試.html:17 {"value":"b","done":false}
// 測試.html:18 {"value":"c","done":false}
// 測試.html:19 {"value":"d","done":false}
// 測試.html:20 {"done":true}
自制迭代器
很多數據對象由于不是可迭代對象,我們可以為其手動創建一個迭代器
與函數不同,這次將其封裝在對象中,并且此后調用方法一致
const myObj1 = {strArr: ['a', 'b', 'c', 'd'],// 在 myObj1 的內部創建一個迭代器[Symbol.iterator]: function () {let index = 0;const Iterator = {next: function () {if (index < myObj1.strArr.length) {return { done: false, value: myObj1.strArr[index++] };} else {return { done: true };}},};return Iterator;},
};// 獲取 myObj1 的迭代器對象
const myIterator = myObj1[Symbol.iterator]();
// 通過迭代器遍歷 myObj1.strArr 的數據
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
console.log(JSON.stringify(myIterator.next()));
// 輸出
// {"done":false,"value":"a"}
// 測試.html:32 {"done":false,"value":"b"}
// 測試.html:33 {"done":false,"value":"c"}
// 測試.html:34 {"done":false,"value":"d"}
// 測試.html:35 {"done":true}
大部分步驟一致,只是在函數前加上[Symbol.iterator]:
而可迭代對象可以使用for of進行遍歷
如下
for(let item of myObj1){console.log(item);
}
//輸出同樣效果
當自定義類復雜時,自制迭代器也就更難寫