ECMAScript中迭代器的深入講解
前言
許多初級(jí)前端開發(fā)者在往中級(jí)邁進(jìn)的過程中,面試經(jīng)常問到的一個(gè)就是迭代器和生成器,其實(shí)在開發(fā)中都用過,但是并不知道這是什么,或者有些許了解但并不夠深入。那這篇文章就對(duì)這一部分開發(fā)者會(huì)有一定的幫助,講清楚迭代器這玩意。
較早的迭代
迭代肯定知道,簡(jiǎn)單理解起來就是循環(huán),在JavaScript 中,計(jì)數(shù)循環(huán)便是最簡(jiǎn)單的一種。示例:
for(let i = 0; i < 9; ++i){ console.log("[ i ]", i); }
迭代的基礎(chǔ)就是循環(huán),它包含幾個(gè)必要條件:
- 可以指定迭代的次數(shù)
- 可以指定每次迭代執(zhí)行的操作
- 每次迭代都在下一次迭代開始前完成
- 順序都是事先定義好的
當(dāng)需要循環(huán)遍歷一個(gè)數(shù)組的時(shí)候,迭代是在一個(gè)有序的集合上進(jìn)行的,「有序」即為數(shù)組中的所有元素都可以按照順序從第一項(xiàng)到最后一項(xiàng)被遍歷到。因?yàn)閿?shù)組有確定的長度,以及每一項(xiàng)都可以通過索引下標(biāo)去獲取,也就是說可以通過索引去遍歷整個(gè)數(shù)組。示例:
const arr = ["a", "b", "c"]; for(let i = 0; i < arr.length; ++i){ console.log(arr[i]); }
但是這種模式必須要事先知道使用的是什么數(shù)據(jù)結(jié)構(gòu),例如數(shù)組,如果換成其它數(shù)據(jù)類型,或者具有隱式順序的數(shù)據(jù)結(jié)構(gòu),那么遍歷的順序就不可確定。
于是在 ES5 中新增了forEach()方法。示例:
const arr = ["a", "b", "c"]; arr.forEach(item=>{ console.log(item); });
這個(gè)方法就不用同數(shù)組索引去遍歷和獲取單項(xiàng)的取值,但無法標(biāo)識(shí)迭代什么時(shí)候結(jié)束,因此僅適用于數(shù)組的遍歷。為了解決這些問題,ES6 之后,JavaScript 支持了迭代器模式。
迭代器模式
迭代器模式是一種非常抽象的說法,可以把它理解成數(shù)組或者集合這一類的對(duì)象,它們的元素是有限的,且互相獨(dú)立無歧義。引用紅寶書的解釋,即為:
迭代器模式(特別是在ECMAScript這個(gè)語境下)描述了一個(gè)方案,即可以把有些結(jié)構(gòu)稱為“可迭代對(duì)象”(iterable),因?yàn)樗鼈儗?shí)現(xiàn)了正式的Iterable接口,而且可以通過迭代器Iterator消費(fèi)。
迭代器工廠函數(shù)
迭代器工廠函數(shù),也就是 Symbol.iterator(),它是大部分內(nèi)置類型都含有的默認(rèn)屬性,通過它暴露 Iterable 接口(可迭代協(xié)議),也就是說要想數(shù)據(jù)類型支持迭代,那么該類型必須支持可迭代協(xié)議。
ECMAScript 中規(guī)定暴露的默認(rèn)迭代器,必須以“Symbol.iterator”作為鍵,返回一個(gè)新的迭代器。檢查是否存在默認(rèn)迭代器屬性的方法也很簡(jiǎn)單。示例:
const obj = {}; const arr = ["a", "b", "c"]; console.log(obj[Symbol.iterator]); // underfined console.log(arr[Symbol.iterator]); // f values() { [native code] } console.log(arr[Symbol.iterator]()); // ArrayIterator {}
當(dāng)然,我們實(shí)際開發(fā)中是不用顯示調(diào)用迭代器工廠函數(shù)的,支持可迭代協(xié)議的數(shù)據(jù)類型會(huì)自動(dòng)兼容接受可迭代對(duì)象的任何語言特性,例如當(dāng)我們使用循環(huán)、for-of、解構(gòu)、擴(kuò)展操作符的時(shí)候,會(huì)自動(dòng)在后臺(tái)調(diào)用提供的可迭代對(duì)象的迭代器工廠函數(shù),從而創(chuàng)建一個(gè)迭代器。
迭代器協(xié)議
迭代器協(xié)議約定迭代器是一種一次性使用的對(duì)象,當(dāng)調(diào)用迭代器工廠函數(shù)后,返回一個(gè)next()方法,每一次迭代成功都會(huì)調(diào)用該方法,得知下一個(gè)迭代的值,如果不調(diào)用,則不確定迭代的當(dāng)前位置。
next()方法返回一個(gè)對(duì)象,包含量屬性:done和value,done 表示是否可以繼續(xù)調(diào)用next()方法獲取下一個(gè)值,意為是否「耗盡」,返回一個(gè) Boolean 值; value 表示可迭代對(duì)象的下一個(gè)值。done 為 true 時(shí),value 則為 underfined。done 為 false 時(shí),則會(huì)繼續(xù)調(diào)用下一個(gè)迭代。示例:
// 可迭代對(duì)象 let arr = ['foo', 'bar'];// 迭代器工廠函數(shù) console.log(arr[Symbol.iterator]);// f values() { [native code] } // 迭代器 let iter = arr[Symbol.iterator](); console.log(iter); // ArrayIterator{} // 執(zhí)行迭代 console.log(iter.next()); // { done: false, value: 'foo' } console.log(iter.next()); // { done: false, value: 'bar' } console.log(iter.next()); // { done: true, value: undefined }
寫在最后
通過迭代器協(xié)議,你可以實(shí)現(xiàn)一個(gè)自定義的迭代器,比如規(guī)定迭代器可以被迭代的次數(shù),或者提前終止迭代。
到此這篇關(guān)于ECMAScript中迭代器的文章就介紹到這了,更多相關(guān)ECMAScript迭代器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)點(diǎn)擊圖片在屏幕中間彈出放大效果
這篇文章主要介紹了js實(shí)現(xiàn)點(diǎn)擊圖片在屏幕中間彈出放大效果,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09layui實(shí)現(xiàn)左側(cè)菜單點(diǎn)擊右側(cè)內(nèi)容區(qū)顯示
這篇文章主要為大家詳細(xì)介紹了layui實(shí)現(xiàn)左側(cè)菜單點(diǎn)擊右側(cè)內(nèi)容區(qū)顯示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Javascript實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了Javascript實(shí)現(xiàn)時(shí)間倒計(jì)時(shí)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11JS一維數(shù)組轉(zhuǎn)化為三維數(shù)組方法
這篇文章主要給大家分享了JS一維數(shù)組轉(zhuǎn)化為三維數(shù)組的方法,下面文章圍繞JS數(shù)組轉(zhuǎn)換的相關(guān)資料展開內(nèi)容,對(duì)大家的學(xué)習(xí)有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-01-01前端項(xiàng)目中正確插入圖片的不同方法和技術(shù)
本文詳細(xì)介紹了在前端項(xiàng)目中插入圖片的不同方法,包括HTML標(biāo)簽、CSS樣式、JavaScript動(dòng)態(tài)加載以及圖片的性能優(yōu)化,其中涉及到的技術(shù)包括響應(yīng)式圖片設(shè)計(jì)、圖片懶加載技術(shù)和圖片格式選擇等,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10JS實(shí)現(xiàn)仿雅虎首頁快捷登錄入口及導(dǎo)航模塊效果
這篇文章主要介紹了JS實(shí)現(xiàn)仿雅虎首頁快捷登錄入口及導(dǎo)航模塊效果,涉及JavaScript響應(yīng)鼠標(biāo)事件遍歷頁面元素的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09如何利用原生JS實(shí)現(xiàn)圖片預(yù)覽加上傳(前后端交互)
在做網(wǎng)站系統(tǒng)時(shí)經(jīng)常會(huì)用到圖片上傳功能,用戶往往希望能看到自己上傳的圖片的樣子,下面這篇文章主要給大家介紹了關(guān)于如何利用原生JS實(shí)現(xiàn)圖片預(yù)覽加上傳,需要的朋友可以參考下2022-01-01如何讓你的JavaScript函數(shù)更加優(yōu)雅詳解
在Js世界中有些操作會(huì)讓你無法理解,但是卻無比優(yōu)雅,下面這篇文章主要給大家介紹了關(guān)于如何讓你的JavaScript函數(shù)更加優(yōu)雅的相關(guān)資料,需要的朋友可以參考下2021-07-07