ES6 迭代器 Iterator使用總結(jié)
Iterator
(迭代器)是 ES6 引入的一種 接口,用于 順序訪問 可迭代對(duì)象(Array
、Set
、Map
、String
、arguments
、自定義對(duì)象等)。
Iterator(迭代器)的作用有三個(gè):
- 為各種數(shù)據(jù)結(jié)構(gòu)提供一個(gè)統(tǒng)一的、簡(jiǎn)便的訪問接口
- 使數(shù)據(jù)結(jié)構(gòu)的成員能夠按某種次序排列
- ES6 創(chuàng)造了一種新的遍歷命令 for…of 循環(huán),Iterator 接口主要供 for…of 消費(fèi)
1. 迭代器的基本概念
(1) 迭代器是什么?
迭代器是一種 特殊對(duì)象,提供 next()
方法,每次調(diào)用都會(huì)返回:
{ value: 當(dāng)前值, done: 是否完成 }
當(dāng) done: true
時(shí),表示迭代結(jié)束。
Iterator 的遍歷過程
// Iterator 的遍歷過程如下: 1. 創(chuàng)建一個(gè)指針對(duì)象,指向當(dāng)前數(shù)據(jù)結(jié)構(gòu)的起始位置 2. 第一次調(diào)用指針對(duì)象的 next 方法,可以將指針指向數(shù)據(jù)結(jié)構(gòu)的第一個(gè)成員 3. 第二次調(diào)用指針對(duì)象的 next 方法,指針就指向數(shù)據(jù)結(jié)構(gòu)的第二個(gè)成員 4. 不斷調(diào)用指針對(duì)象的 next 方法,直到它指向數(shù)據(jù)結(jié)構(gòu)的結(jié)束位置 // 每一次調(diào)用 next 方法,都會(huì)返回一個(gè)包含 value 和 done 兩個(gè)屬性的對(duì)象 { value: 當(dāng)前成員的值, done: 布爾值,表示遍歷是否結(jié)束 }
2. 生成迭代器
(1) 手動(dòng)創(chuàng)建迭代器
function createIterator(arr) { let index = 0; return { next: function () { return index < arr.length ? { value: arr[index++], done: false } : { value: undefined, done: true }; } }; } let iterator = createIterator(["a", "b", "c"]); console.log(iterator.next()); // { value: 'a', done: false } console.log(iterator.next()); // { value: 'b', done: false } console.log(iterator.next()); // { value: 'c', done: false } console.log(iterator.next()); // { value: undefined, done: true }
?? 每次 next()
調(diào)用,都會(huì)返回 value
并前進(jìn)。
(2) 使用 Symbol.iterator
所有 可迭代對(duì)象(Array
、Set
、Map
等)都有 默認(rèn)的迭代器,可以用 Symbol.iterator
訪問:
let arr = ["x", "y", "z"]; let iterator = arr[Symbol.iterator](); console.log(iterator.next()); // { value: 'x', done: false } console.log(iterator.next()); // { value: 'y', done: false } console.log(iterator.next()); // { value: 'z', done: false } console.log(iterator.next()); // { value: undefined, done: true }
?? 數(shù)組、字符串、Set、Map 都有 Symbol.iterator
,可直接迭代。
(3) 自定義對(duì)象的迭代器
普通對(duì)象沒有默認(rèn)迭代器,需手動(dòng)實(shí)現(xiàn):
let myObj = { data: [10, 20, 30], [Symbol.iterator]: function () { let index = 0; return { next: () => { return index < this.data.length ? { value: this.data[index++], done: false } : { value: undefined, done: true }; } }; } }; let iter = myObj[Symbol.iterator](); console.log(iter.next()); // { value: 10, done: false } console.log(iter.next()); // { value: 20, done: false } console.log(iter.next()); // { value: 30, done: false } console.log(iter.next()); // { value: undefined, done: true }
?? 對(duì)象沒有默認(rèn)迭代器,需實(shí)現(xiàn) Symbol.iterator
才能用 for...of
。
3. for...of 遍歷迭代器
所有 實(shí)現(xiàn) Symbol.iterator
的對(duì)象,都可以用 for...of
遍歷:
let arr = ["A", "B", "C"]; for (let char of arr) { console.log(char); } // A // B // C
?? 相比 forEach()
,for...of
可與 break
、continue
配合使用。
4. 可迭代對(duì)象
? 可以使用 for...of
、Symbol.iterator
的對(duì)象
Array
String
Set
Map
arguments
NodeList
- 自定義對(duì)象(需實(shí)現(xiàn)
Symbol.iterator
)
5. Set 和 Map 的迭代器
(1) Set
迭代
let mySet = new Set(["apple", "banana", "cherry"]); let setIter = mySet[Symbol.iterator](); console.log(setIter.next()); // { value: 'apple', done: false } console.log(setIter.next()); // { value: 'banana', done: false } console.log(setIter.next()); // { value: 'cherry', done: false } console.log(setIter.next()); // { value: undefined, done: true }
?? Set
按插入順序存儲(chǔ),迭代返回唯一值。
(2) Map
迭代
let myMap = new Map([ ["name", "Alice"], ["age", 25] ]); for (let [key, value] of myMap) { console.log(key, value); } // name Alice // age 25
?? Map
迭代時(shí)返回 [key, value]
數(shù)組。
6. 迭代器 vs 生成器
特性 | 迭代器 (Iterator) | 生成器 (Generator) |
---|---|---|
創(chuàng)建方式 | 手動(dòng)實(shí)現(xiàn) next() | function* 生成 |
使用 Symbol.iterator | 需要手動(dòng)實(shí)現(xiàn) | 生成器自動(dòng)實(shí)現(xiàn) |
可暫停執(zhí)行 | ? 否 | ? 是(可 yield ) |
示例:生成器
function* generatorFunction() { yield "A"; yield "B"; yield "C"; } let gen = generatorFunction(); console.log(gen.next()); // { value: 'A', done: false } console.log(gen.next()); // { value: 'B', done: false } console.log(gen.next()); // { value: 'C', done: false } console.log(gen.next()); // { value: undefined, done: true }
?? 生成器更簡(jiǎn)潔,支持 yield
暫停執(zhí)行。
7. Iterator 使用場(chǎng)景
7.1 解構(gòu)賦值
// 對(duì)數(shù)組和 Set 結(jié)構(gòu)進(jìn)行解構(gòu)賦值時(shí),會(huì)默認(rèn)調(diào)用 Iterator 接口 let set = new Set().add('a').add('b').add('c'); let [x, y] = set; // x='a'; y='b'
7.2 擴(kuò)展運(yùn)算符
// 擴(kuò)展運(yùn)算符(...)也會(huì)調(diào)用默認(rèn)的 Iterator 接口 let str = 'hello'; [...str] // ['h', 'e', 'l', 'l', 'o'] let arr = ['b', 'c']; ['a', ...arr, 'd'] // ['a', 'b', 'c', 'd']
7.3 yield*
// yield* 后面跟的是一個(gè)可遍歷的結(jié)構(gòu),它會(huì)調(diào)用該結(jié)構(gòu)的遍歷器接口 let generator = function* () { yield 1; yield* [2, 3, 4]; yield 5; }; for (let v of generator()) { console.log(v); } // 1, 2, 3, 4, 5
8. 注意事項(xiàng)
8.1 對(duì)象的 for…of 循環(huán)
// 對(duì)象默認(rèn)不具備 Iterator 接口,不能直接使用 for...of let obj = { a: 1, b: 2, c: 3 }; for (let value of obj) { console.log(value); // TypeError: obj is not iterable } // 正確的遍歷對(duì)象方式 // 1. 使用 Object.keys() for (let key of Object.keys(obj)) { console.log(key + ': ' + obj[key]); } // 2. 使用 Object.entries() for (let [key, value] of Object.entries(obj)) { console.log(key + ': ' + value); }
8.2 Iterator 接口與 Generator 函數(shù)
// 使用 Generator 函數(shù)實(shí)現(xiàn) Iterator 接口 let obj = { *[Symbol.iterator]() { yield 'hello'; yield 'world'; } }; for (let x of obj) { console.log(x); } // hello // world
9. 最佳實(shí)踐
9.1 為類部署 Iterator 接口
class Collection { constructor() { this.items = []; } add(item) { this.items.push(item); } *[Symbol.iterator]() { for (let item of this.items) { yield item; } } } let collection = new Collection(); collection.add('foo'); collection.add('bar'); for (let value of collection) { console.log(value); } // foo // bar
9.2 異步迭代器
// ES2018 引入了異步迭代器 const asyncIterable = { async *[Symbol.asyncIterator]() { yield 'hello'; yield 'async'; yield 'iteration'; } }; (async () => { for await (const x of asyncIterable) { console.log(x); } })(); // hello // async // iteration
10. 適用場(chǎng)景
? 適用于
遍歷數(shù)組、字符串、Set、Map自定義可迭代對(duì)象流式處理數(shù)據(jù)(類似分頁(yè)加載)避免一次性加載大數(shù)據(jù)(生成器)
11. 總結(jié)
Iterator
是 ES6 提供的一種接口,用于順序訪問集合。Symbol.iterator
讓對(duì)象變成可迭代,可用于for...of
、spread
。Set
、Map
、Array
、String
默認(rèn)實(shí)現(xiàn)Symbol.iterator
,可直接迭代。- 生成器 (
Generator
) 自動(dòng)創(chuàng)建迭代器,可暫停執(zhí)行 (yield
),更強(qiáng)大。
到此這篇關(guān)于ES6 迭代器 Iterator使用總結(jié)的文章就介紹到這了,更多相關(guān)ES6 迭代器 Iterator使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
讓firefox支持IE的一些方法的javascript擴(kuò)展函數(shù)代碼
因?yàn)橐恍┐a,只能在IE下實(shí)現(xiàn),如果用firefox實(shí)現(xiàn)就必須用一些擴(kuò)展函數(shù)。2010-01-01js驗(yàn)證身份證號(hào)有效性并提示對(duì)應(yīng)信息
這篇文章主要介紹了一段超級(jí)全面的二代身份證號(hào)碼驗(yàn)證程序,2015-10-10微信小程序?qū)崿F(xiàn)多選框全選與反全選及購(gòu)物車中刪除選中的商品功能
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)多選框全選與反全選及購(gòu)物車中刪除選中的商品功能,本文通過截圖實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2019-12-12純js代碼實(shí)現(xiàn)簡(jiǎn)單計(jì)算器
這篇文章主要介紹了純js代碼實(shí)現(xiàn)簡(jiǎn)單計(jì)算器,功能超簡(jiǎn)單,實(shí)現(xiàn)加減乘除簡(jiǎn)單運(yùn)算,感興趣的小伙伴們可以參考一下2015-12-12uniapp和uniCloud開發(fā)中常出現(xiàn)的問題及解決匯總
使用uni 開發(fā)一段時(shí)間了,下面這篇文章主要給大家介紹了關(guān)于uniapp和uniCloud開發(fā)中常出現(xiàn)的問題及解決的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12JS禁用右鍵、禁用Ctrl+u、禁用Ctrl+s、禁用F12的實(shí)現(xiàn)代碼
最近項(xiàng)目需要屏蔽客戶端的一些操作,加大查看源碼等難度,特整理一下這個(gè)js,也防止客戶端用戶誤操作,破解方放也很簡(jiǎn)單這里就不多說了2020-10-10