首頁 web前端 js教程 JavaScript ES6的迭代器與生成器介紹

JavaScript ES6的迭代器與生成器介紹

Aug 21, 2017 am 09:44 AM
javascript js 介紹

這篇文章主要介紹了深入理解ES6的迭代器與生成器,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧

本文介紹了深入理解ES6的迭代器與生成器,分享給大家,具體如下:

##循環語句的問題


var colors = ["red", "green", "blue"];
for(var i=0; i<colors.length; i++){
  console.log(colors[i]);
}
登入後複製

在ES6之前,這種標準的for循環,透過變數來追蹤陣列的索引。如果多個循環嵌套需要追蹤多個變量,程式碼複雜度會大大增加,也容易產生錯用循環變量的bug。

迭代器的出現旨在消除這種複雜性並減少循環中的錯誤。

什麼是迭代器

我們先感受一下用ES5語法模擬建立一個迭代器:


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循環【暫時先忘記ES6的for-of循環新特性】:


var colors = ["red", "green", "blue"];
var iterator = createIterator(colors);
while(!iterator.next().done){
  console.log(iterator.next().value);
}
登入後複製

what?,消除循環變數而已,需要搞這麼麻煩,程式碼上不是得不償失了嗎?


#並非如此,畢竟createIterator()只要寫一次,就可以一直重複使用。不過ES6引入了生成器對象,可以讓創建迭代器的過程變得更簡單。

什麼是生成器

#產生器是一種傳回迭代器的函數,透過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的生成,大大簡化了迭代器的建立過程。我們給生成器函數createIterator()傳入一個items數組,函數內部,for循環不斷從數組中生成新的元素放入迭代器中,每遇到一個yield語句循環都會停止;每次調用迭代器的next ()方法,循環便繼續運轉並停止在下一條yield語句處。

生成器的建立方式

生成器是函數:


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循環新特性for-of:


var colors = ["red", "green", "blue"];
for(let color of colors){
  console.log(color);
}
登入後複製

for-of循環,可作用在可迭代在物件上,正是利用了可迭代物件上的預設迭代器。大致過程是:for-of迴圈每執行一次都會呼叫可迭代物件的next()方法,並將迭代器傳回的結果物件的value屬性儲存在變數中,迴圈將繼續執行此過程直到傳回物件的done屬性的值為true。

如果只需要迭代數組或集合中的值,用for-of迴圈取代for迴圈是個不錯的選擇。

存取預設迭代器

可迭代對象,都有一個Symbol.iterator方法,for-of循環時,透過呼叫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引擎中執行for-of迴圈語句也是類似的處理過程。

用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
登入後複製

建立可迭代物件



##當我們在建立物件時,為Symbol.iterator屬性新增一個生成器,則可以將其變成可迭代物件:
  • let collection = {
      items: [],
      *[Symbol.iterator]() { // 将生成器赋值给对象的Symbol.iterator属性来创建默认的迭代器
        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循环中,如果没有显式指定则使用默认的迭代器。按常规使用习惯,我们很容易猜到,数组和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循环配合解构特性,操纵数据会更方便:


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]
登入後複製

展开运算符可以操作所有的可迭代对象,并根据默认迭代器来选取要引用的值,从迭代器读取所有值。然后按返回顺序将它们依次插入到数组中。因此如果想将可迭代对象转换为数组,用展开运算符是最简单的方法。

以上是JavaScript ES6的迭代器與生成器介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

wapi是什麼東西詳細介紹 wapi是什麼東西詳細介紹 Jan 07, 2024 pm 09:14 PM

wapi這個名詞使用者可能在使用網路得時候見過過,但是對於一部分人來說肯定都不知道wapi是什麼,下面就帶來了詳細介紹,幫助不知道小伙伴去了解。 wapi是什麼東西:答:wapi是無線區域網路鑑別和保密的基礎架構。這就像紅外線和藍牙等功能一樣,一般都覆蓋在辦公大樓等地方的附近。基本上都是為一個小部門所有的,所以這個功能涉及的範圍只有幾公里。 wapi相關介紹:1、wapi是無線區域網路裡面的一種傳輸協定。 2.這款技術是可以去避免窄頻帶通訊的問題,可以更好的去進行傳播。 3.只要只需要一個代碼就可以去傳送訊號了

詳解win11能否運行PUBG遊戲 詳解win11能否運行PUBG遊戲 Jan 06, 2024 pm 07:17 PM

pubg又稱絕地求生,是一款非常經典的射擊大逃殺類型遊戲,從2016年火爆以來一直擁有非常多的玩家。在最近的win11系統推出後,就有不少玩家想要在win11上游玩它,下面就跟著小編來看看win11是否可以玩pubg吧。 win11能玩pubg嗎:答:win11可以玩pubg。 1.在win11推出之初,因為win11需要開啟tpm的緣故,所以導致很多玩家被pubg封號處理了。 2.不過後來根據玩家的回饋,藍洞方面已經解決了這個問題,目前已經可以在win11中正常玩pubg了。 3.如果大家遇到了pub

建議:優秀JS開源人臉偵測辨識項目 建議:優秀JS開源人臉偵測辨識項目 Apr 03, 2024 am 11:55 AM

人臉偵測辨識技術已經是一個比較成熟且應用廣泛的技術。而目前最廣泛的網路應用語言非JS莫屬,在Web前端實現人臉偵測辨識相比後端的人臉辨識有優勢也有弱勢。優點包括減少網路互動、即時識別,大大縮短了使用者等待時間,提高了使用者體驗;弱勢是:受到模型大小限制,其中準確率也有限。如何在web端使用js實現人臉偵測呢?為了實現Web端人臉識別,需要熟悉相關的程式語言和技術,如JavaScript、HTML、CSS、WebRTC等。同時也需要掌握相關的電腦視覺和人工智慧技術。值得注意的是,由於Web端的計

i5處理器是否能裝win11詳細介紹 i5處理器是否能裝win11詳細介紹 Dec 27, 2023 pm 05:03 PM

i5是英特爾旗下的一系列處理器,擁有到現在11代i5的各種不同版本,每一代都有不同效能。因此對於i5處理器是否能夠安裝win11,還要看是第幾代的處理器,下面就跟著小編一起來分別了解一下吧。 i5處理器能裝win11嗎:答:i5處理器能裝win11。一、第八代及之後的i51、第八代及後續的i5處理器是能夠滿足微軟的最低配置需求的。 2.因此我們只需要進入微軟網站,下載一個「win11安裝助手」3、下載完成後,運行該安裝助手,根據提示進行操作就可以安裝win11了。二、第八代之前的i51、第八代之

介紹最新的Win 11聲音調法方法 介紹最新的Win 11聲音調法方法 Jan 08, 2024 pm 06:41 PM

很多用戶更新了最新的win11之後發現自己系統的聲音有了些許的變化,但是又不知道該怎麼去進行調整,所以今天本站就給你們帶來了電腦最新win11聲音調法介紹,操作不難而且選擇多樣,快來一起下載試試吧。電腦最新系統windows11聲音如何調1、先右鍵點選桌面右下角的聲音圖標,並選擇「播放設定」。 2、然後進入設定中點選播放列中的「揚聲器」。 3、隨後點選右下方的「屬性」。 4.點選屬性中的「增強」選項列。 5.此時如果「禁用所有聲音效果」前的√勾上了就把他取消。 6、之後就可以選擇下面的聲音效果來進行設定並點

PyCharm新手指南:取代功能全面解析 PyCharm新手指南:取代功能全面解析 Feb 25, 2024 am 11:15 AM

PyCharm是一款功能強大的Python整合開發環境,具有豐富的功能與工具,能夠大幅提升開發效率。其中,替換功能是開發過程中常用的功能之一,能夠幫助開發者快速修改程式碼並提高程式碼品質。本文將詳細介紹PyCharm的替換功能,並結合具體的程式碼範例,幫助新手更好地掌握和使用該功能。替換功能簡介PyCharm的替換功能可以幫助開發者在程式碼中快速替換指定的文本

詳細介紹電腦中的印表機驅動程式位置 詳細介紹電腦中的印表機驅動程式位置 Jan 08, 2024 pm 03:29 PM

許多用戶在電腦上安裝了印表機驅動程序,但卻不知道如何找到它們。因此,今天我為大家帶來了詳細介紹印表機驅動程式在電腦中的位置,對於還不了解的用戶,快來看看吧印表機驅動在電腦哪裡找重新撰寫內容而不改變原義時,需要將語言改寫為中文,不需要出現原句首先,建議使用第三方軟體進行搜尋2、在右上角找到"工具箱"3、在下方找到並點選「裝置管理員」。改寫後的句子:3、在底部找到並點擊“裝置管理員”4、然後打開“列印佇列”,然後找到你的印表機裝置。此次是你的印表機名稱型號。 5.右鍵印表機設備,就能夠去更新或卸載我

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

See all articles