這篇文章將為大家詳細講解有關ES6中迭代器與生成器的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領域值得信任、有價值的長期合作伙伴,公司提供的服務項目有:空間域名、虛擬空間、營銷軟件、網站建設、阿克塞哈薩克族自治網站維護、網站推廣。具體如下:
循環(huán)語句的問題
var colors = ["red", "green", "blue"]; for(var i=0; i<colors.length; i++){ console.log(colors[i]); }
在ES6之前,這種標準的for循環(huán),通過變量來跟蹤數組的索引。如果多個循環(huán)嵌套就需要追蹤多個變量,代碼復雜度會大大增加,也容易產生錯用循環(huán)變量的bug。
迭代器的出現旨在消除這種復雜性并減少循環(huán)中的錯誤。
什么是迭代器
我們先感受一下用ES5語法模擬創(chuàng)建一個迭代器:
function createIterator(items) { var i = 0; return { // 返回一個迭代器對象 next: function() { // 迭代器對象一定有個next()方法 var done = (i >= items.length); var value = !done ? items[i++] : undefined; return { // next()方法返回結果對象 value: value, done: done }; } }; } var iterator = createIterator([1, 2, 3]); console.log(iterator.next()); // "{ value: 1, done: false}" console.log(iterator.next()); // "{ value: 2, done: false}" console.log(iterator.next()); // "{ value: 3, done: false}" console.log(iterator.next()); // "{ value: undefiend, done: true}" // 之后所有的調用都會返回相同內容 console.log(iterator.next()); // "{ value: undefiend, done: true}"
以上,我們通過調用createIterator()函數,返回一個對象,這個對象存在一個next()方法,當next()方法被調用時,返回格式{ value: 1, done: false}的結果對象。
因此,我們可以這么定義:迭代器是一個擁有next()方法的特殊對象,每次調用next()都返回一個結果對象。
借助這個迭代器對象,我們來改造剛開始那個標準的for循環(huán)【暫時先忘記ES6的for-of循環(huán)新特性】:
var colors = ["red", "green", "blue"]; var iterator = createIterator(colors); while(!iterator.next().done){ console.log(iterator.next().value); }
what?,消除循環(huán)變量而已,需要搞這么麻煩,代碼上不是得不償失了嗎?
并非如此,畢竟createIterator()只需寫一次,就可以一直復用。不過ES6引入了生成器對象,可以讓創(chuàng)建迭代器的過程變得更加簡單。
什么是生成器
生成器是一種返回迭代器的函數,通過function關鍵字后的星號(*)來表示,函數中會用到新的關鍵字yield。
function *createIterator(items) { for(let i=0; i<items.length; i++) { yield items[i]; } } let iterator = createIterator([1, 2, 3]); // 既然生成器返回的是迭代器,自然就可以調用迭代器的next()方法 console.log(iterator.next()); // "{ value: 1, done: false}" console.log(iterator.next()); // "{ value: 2, done: false}" console.log(iterator.next()); // "{ value: 3, done: false}" console.log(iterator.next()); // "{ value: undefiend, done: true}" // 之后所有的調用都會返回相同內容 console.log(iterator.next()); // "{ value: undefiend, done: true}"
上面,我們用ES6的生成,大大簡化了迭代器的創(chuàng)建過程。我們給生成器函數createIterator()傳入一個items數組,函數內部,for循環(huán)不斷從數組中生成新的元素放入迭代器中,每遇到一個yield語句循環(huán)都會停止;每次調用迭代器的next()方法,循環(huán)便繼續(xù)運行并停止在下一條yield語句處。
生成器的創(chuàng)建方式
生成器是個函數:
function *createIterator(items) { ... }
可以用函數表達式方式書寫:
let createIterator = function *(item) { ... }
也可以添加到對象中,ES5風格對象字面量:
let o = { createIterator: function *(items) { ... } }; let iterator = o.createIterator([1, 2, 3]);
ES6風格的對象方法簡寫方式:
let o = { *createIterator(items) { ... } }; let iterator = o.createIterator([1, 2, 3]);
可迭代對象
在ES6中,所有的集合對象(數組、Set集合及Map集合)和字符串都是可迭代對象,可迭代對象都綁定了默認的迭代器。
來了來了,姍姍來遲的ES6循環(huán)新特性for-of:
var colors = ["red", "green", "blue"]; for(let color of colors){ console.log(color); }
for-of循環(huán),可作用在可迭代對象上,正是利用了可迭代對象上的默認迭代器。大致過程是:for-of循環(huán)每執(zhí)行一次都會調用可迭代對象的next()方法,并將迭代器返回的結果對象的value屬性存儲在變量中,循環(huán)將繼續(xù)執(zhí)行這一過程直到返回對象的done屬性的值為true。
如果只需要迭代數組或集合中的值,用for-of循環(huán)代替for循環(huán)是個不錯的選擇。
訪問默認迭代器
可迭代對象,都有一個Symbol.iterator方法,for-of循環(huán)時,通過調用colors數組的Symbol.iterator方法來獲取默認迭代器的,這一過程是在JavaScript引擎背后完成的。
我們可以主動獲取一下這個默認迭代器來感受一下:
let values = [1, 2, 3]; let iterator = values[Symbol.iterator](); console.log(iterator.next()); // "{ value: 1, done: false}" console.log(iterator.next()); // "{ value: 2, done: false}" console.log(iterator.next()); // "{ value: 3, done: false}" console.log(iterator.next()); // "{ value: undefined, done: true}"
在這段代碼中,通過Symbol.iterator獲取了數組values的默認迭代器,并用它遍歷數組中的元素。在JavaScript引擎中執(zhí)行for-of循環(huán)語句也是類似的處理過程。
用Symbol.iterator屬性來檢測對象是否為可迭代對象:
function isIterator(object) { return typeof object[Symbol.iterator] === "function"; } console.log(isIterable([1, 2, 3])); // true console.log(isIterable(new Set())); // true console.log(isIterable(new Map())); // true console.log(isIterable("Hello")); // true
創(chuàng)建可迭代對象
當我們在創(chuàng)建對象時,給Symbol.iterator屬性添加一個生成器,則可以將其變成可迭代對象:
let collection = { items: [], *[Symbol.iterator]() { // 將生成器賦值給對象的Symbol.iterator屬性來創(chuàng)建默認的迭代器 for(let item of this.items) { yield item; } } }; collection.items.push(1); collection.items.push(2); collection.items.push(3); for(let x of collection) { console.log(x); }
內建迭代器
ES6中的集合對象,數組、Set集合和Map集合,都內建了三種迭代器:
entries() 返回一個迭代器,其值為多個鍵值對。如果是數組,第一個元素是索引位置;如果是Set集合,第一個元素與第二個元素一樣,都是值。
values() 返回一個迭代器,其值為集合的值。
keys() 返回一個迭代器,其值為集合中的所有鍵名。如果是數組,返回的是索引;如果是Set集合,返回的是值(Set的值被同時用作鍵和值)。
不同集合的默認迭代器
每個集合類型都有一個默認的迭代器,在for-of循環(huán)中,如果沒有顯式指定則使用默認的迭代器。按常規(guī)使用習慣,我們很容易猜到,數組和Set集合的默認迭代器是values(),Map集合的默認迭代器是entries()。
請看以下示例:
let colors = [ "red", "green", "blue"]; let tracking = new Set([1234, 5678, 9012]); let data = new Map(); data.set("title", "Understanding ECMAScript 6"); data.set("format", "print"); // 與調用colors.values()方法相同 for(let value of colors) { console.log(value); } // 與調用tracking.values()方法相同 for(let num of tracking) { console.log(num); } // 與調用data.entries()方法相同 for(let entry of data) { console.log(entry); }
這段代碼會輸入以下內容:
"red"
"green"
"blue"
1234
5678
9012
["title", "Understanding ECMAScript 6"]
["format", "print"]
for-of循環(huán)配合解構特性,操縱數據會更方便:
for(let [key, value] of data) { console.log(key + "=" + value); }
展開運算符操縱可迭代對象
let set = new Set([1, 2, 3, 4, 5]), array = [...set]; console.log(array); // [1,2,3,4,5]
展開運算符可以操作所有的可迭代對象,并根據默認迭代器來選取要引用的值,從迭代器讀取所有值。然后按返回順序將它們依次插入到數組中。因此如果想將可迭代對象轉換為數組,用展開運算符是最簡單的方法。
關于“ES6中迭代器與生成器的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
另外有需要云服務器可以了解下創(chuàng)新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
名稱欄目:ES6中迭代器與生成器的示例分析-創(chuàng)新互聯
文章起源:http://jinyejixie.com/article24/ddshce.html
成都網站建設公司_創(chuàng)新互聯,為您提供ChatGPT、商城網站、搜索引擎優(yōu)化、標簽優(yōu)化、全網營銷推廣、App開發(fā)
聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯