首頁 web前端 js教程 ES6中迭代器的原理與可迭代物件的介紹(附範例)

ES6中迭代器的原理與可迭代物件的介紹(附範例)

Oct 29, 2018 pm 03:34 PM
es6 iterator javascript node.js 產生器 迭代器

這篇文章帶給大家的內容是關於ES6中迭代器的原理與可迭代物件的介紹(附範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

ES6 新的陣列方法、集合、for-of 迴圈、展開運算子(...)甚至非同步程式設計都依賴迭代器(Iterator )實作。本文會詳解ES6 的迭代器與生成器,並進一步挖掘可迭代物件的內部原理與使用方法

一、迭代器的原理

在程式語言中處理陣列或集合時,使用循環語句必須要初始化一個變數記錄迭代位置,而程式化地使用迭代器可以簡化這個資料運算

如何設計一個迭代器呢?

迭代器的本身是一個對象,這個對像有next( ) 方法返回結果對象,這個結果對像有下一個返回值value、迭代完成布爾值done,模擬創建一個簡單迭代器如下:

function createIterator(iterms) {
  let i = 0
  return {
    next() {
      let done = (i >= iterms.length)
      let value = !done ? iterms[i++] : undefined
      return {
        done,
        value
      }
    }
  }
}

let arrayIterator = createIterator([1, 2, 3])

console.log(arrayIterator.next()) // { done: false, value: 1 }
console.log(arrayIterator.next()) // { done: false, value: 2 }
console.log(arrayIterator.next()) // { done: false, value: 3 }
console.log(arrayIterator.next()) // { done: true, value: undefined }
登入後複製
對上述語法感到困惑的,可參考:ES6中物件的新功能與解構賦值的詳解(程式碼範例)

每次呼叫迭代器的next( ) 都會返回下一個對象,直到資料集被用盡。

ES6 中迭代器的編寫規則類似,但引入了生成器對象,更簡單的創建迭代器對象

二、創建迭代器

ES6 封裝了一個生成器用來建立迭代器。顯然生成器是傳回迭代器的函數,這個函數透過 function 後的星號(*)表示,並使用新的內部專用關鍵字yield指定迭代器 next( ) 方法的傳回值。

如何使用 ES6 生成器建立一個迭代器呢?一個簡單的例子如下:

function *createIterator() {
  yield 123;
  yield 'someValue'
}

let someIterator = createIterator()

console.log(someIterator.next()) // { value: 123, done: false }
console.log(someIterator.next()) // { value: 'someValue', done: false }
console.log(someIterator.next()) // { value: undefined, done: true }
登入後複製

使用yield關鍵字可以傳回任意值或表達式,可以為迭代器批量添加元素:

// let createIterator = function *(items) { // 生成器函数表达式
function *createIterator(items) {
  for (let i = 0; i < items.length; i++) {
    yield items[i]
  }
}

let someIterator = createIterator([123, &#39;someValue&#39;])

console.log(someIterator.next()) // { value: 123, done: false }
console.log(someIterator.next()) // { value: &#39;someValue&#39;, done: false }
console.log(someIterator.next()) // { value: undefined, done: true }
登入後複製

由於生成器本身是函數,所以可添加到物件中,使用方式如下:

let obj = {
  // createIterator: function *(items) { // ES5
  *createIterator(items) { // ES6
    for (let i = 0; i < items.length; i++) {
      yield items[i]
    }
  }
}
let someIterator = obj.createIterator([123, &#39;someValue&#39;])
登入後複製
產生器函數的一個特點是,當執行完一句yield 語句後函數會自動停止執行,再次呼叫迭代器的next( ) 方法才會繼續執行下一個yield 語句。
這種自動中止函數執行的能力衍生出許多高階用法。

三、可迭代對象

在ES6 中常用的集合對象(數組、Set/Map集合)和字串都是可迭代對象,這些對像都有預設的迭代器和Symbol.iterator屬性。

透過生成器建立的迭代器也是可迭代對象,因為生成器預設會為Symbol.iterator屬性賦值。

3.1 Symbol.iterator

可迭代物件具有Symbol.iterator屬性,即具有Symbol.iterator屬性的物件都有預設迭代器。

我們可以用Symbol.iterator來存取物件的預設迭代器,例如對於一個陣列:

let list = [11, 22, 33]
let iterator = list[Symbol.iterator]()
console.log(iterator.next()) // { value: 11, done: false }
登入後複製

Symbol.iterator獲得了數組這個可迭代物件的預設迭代器,並操作它遍歷了數組中的元素。

反之,我們可以用Symbol.iterator來偵測物件是否為可迭代物件:

function isIterator(obj) {
  return typeof obj[Symbol.iterator] === &#39;function&#39;
}

console.log(isIterator([11, 22, 33])) // true
console.log(isIterator(&#39;sometring&#39;)) // true
console.log(isIterator(new Map())) // true
console.log(isIterator(new Set())) // true
console.log(isIterator(new WeakMap())) // false
console.log(isIterator(new WeakSet())) // false
登入後複製

顯然陣列、Set/Map 集合、字串都是可迭代對象,而WeakSet/WeakMap集合(弱引用集合)是不可迭代的。

3.2 建立可迭代物件

預設情況下,自訂的物件都是不可迭代的。

剛剛講過,透過生成器建立的迭代器也是一種可迭代對象,生成器預設會為Symbol.iterator屬性賦值。

那要如何將自訂物件變成可迭代物件呢?透過為Symbol.iterator屬性新增一個生成器:

let collection = {
  items: [11,22,33],
  *[Symbol.iterator]() {
    for (let item of this.items){
      yield item
    }
  }
}

console.log(isIterator(collection)) // true

for (let item of collection){
  console.log(item) // 11 22 33
}
登入後複製

陣列 items 是可迭代對象,collection 物件透過給Symbol.iterator屬性賦值也成為可迭代物件。

3.3 for-of

#注意到上個栗子使用了for-of代替索引循環,for-of是 ES6 為可迭代物件新加入的特性。

思考一下for-of迴圈的實作原理。

對於使用for-of的可迭代對象,for-of每執行一次就會調用這個可迭代對象的next( ),並將返回結果存儲在一個變數中,持續執行直到可迭代對象done 屬性值為false。

// 迭代一个字符串
let str = &#39;somestring&#39;

for (let item of str){
  console.log(item) // s o m e s t r i n g
}
登入後複製

本質上來說,for-of呼叫str 字串的Symbol.iterator屬性方法取得迭代器(這個過程由JS 引擎完成),然後多次呼叫next( ) 方法將物件value 值儲存在item 變數。

將for-of用於不可迭代物件、null 或 undefined 會報錯!

3.4 展開運算子(...)

ES6 語法糖展開運算子(...)也是服務於可迭代對象,即只可以「展開」陣列、集合、字串、自訂可迭代物件。

以下栗子輸出不同可迭代物件展開運算子計算的結果:

let str = &#39;somestring&#39;
console.log(...str) // s o m e s t r i n g
let set = new Set([1, 2, 2, 5, 8, 8, 8, 9])
console.log(set) // Set { 1, 2, 5, 8, 9 }
console.log(...set) // 1 2 5 8 9
let map = new Map([[&#39;name&#39;, &#39;jenny&#39;], [&#39;id&#39;, 123]])
console.log(map) // Map { &#39;name&#39; => 'jenny', 'id' => 123 }
console.log(...map) // [ 'name', 'jenny' ] [ 'id', 123 ]
let num1 = [1, 2, 3], num2 = [7, 8, 9]
console.log([...num1, ...num2]) // [ 1, 2, 3, 7, 8, 9 ]
let udf
console.log(...udf) // TypeError: undefined is not iterable
登入後複製

由上述程式碼可以看出,展開運算子(...)可以方便地將可迭代物件轉換為數組。同for-of一樣,展開運算子(...)用於不可迭代物件、null 或 undefined 會報錯!

四.預設迭代器

ES6 为很多内置对象提供了默认的迭代器,只有当内建的迭代器不能满足需求时才自己创建迭代器。

ES6 的 三个集合对象:Set、Map、Array 都有默认的迭代器,常用的如values()方法、entries()方法都返回一个迭代器,其值区别如下:

entries():多个键值对

values():集合的值

keys():集合的键

调用以上方法都可以得到集合的迭代器,并使用for-of循环,示例如下:

/******** Map ***********/
let map = new Map([['name', 'jenny'], ['id', 123]])

for(let item of map.entries()){
  console.log(item) // [ 'name', 'jenny' ]  [ 'id', 123 ]
}
for(let item of map.keys()){
  console.log(item) // name id
}
for (let item of map.values()) {
  console.log(item) // jenny 123
}

/******** Set ***********/
let set = new Set([1, 4, 4, 5, 5, 5, 6, 6,])

for(let item of set.entries()){
  console.log(item) // [ 1, 1 ] [ 4, 4 ] [ 5, 5 ] [ 6, 6 ]
}

/********* Array **********/
let array = [11, 22, 33]

for(let item of array.entries()){
  console.log(item) // [ 0, 11 ] [ 1, 22 ] [ 2, 33 ]
}
登入後複製

此外 String 和 NodeList 类型都有默认的迭代器,虽然没有提供其它的方法,但可以用for-of循环

以上是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脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 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)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1325
25
PHP教程
1272
29
C# 教程
1252
24
如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

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

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

Golang迭代器實作及使用詳解 Golang迭代器實作及使用詳解 Mar 17, 2024 pm 09:21 PM

Golang是一個快速、有效率的靜態編譯型語言,其簡潔的語法和強大的效能讓它在軟體開發領域備受青睞。在Golang中,迭代器(Iterator)是一種常用的設計模式,用於遍歷集合中的元素而無需暴露集合的內部結構。本文將詳細介紹如何在Golang中實作和使用迭代器,透過具體的程式碼範例幫助讀者更好地理解。 1.迭代器的定義在Golang中,迭代器通常由一個介面和實

Java Iterator 與 Iterable:揭秘迭代器與可迭代物件的世界 Java Iterator 與 Iterable:揭秘迭代器與可迭代物件的世界 Feb 19, 2024 pm 02:15 PM

在Java程式設計中,Iterator和Iterable介面是用來處理集合中元素的重要工具。 Iterator介面提供了對集合元素進行迭代存取的方法,而Iterable介面則定義了集合的可迭代性,使集合中的元素可以透過Iterator存取。這兩者的緊密配合,為我們提供了遍歷集合元素的通用方法。 Iterator介面Iterator介面定義了以下方法:booleanhasNext():檢查集合中是否還有元素。 Enext():傳回集合中的下一個元素。 voidremove():移除目前元素。 Iterable接

如何在JavaScript中取得HTTP狀態碼的簡單方法 如何在JavaScript中取得HTTP狀態碼的簡單方法 Jan 05, 2024 pm 01:37 PM

JavaScript中的HTTP狀態碼取得方法簡介:在進行前端開發中,我們常常需要處理與後端介面的交互,而HTTP狀態碼就是其中非常重要的一部分。了解並取得HTTP狀態碼有助於我們更好地處理介面傳回的資料。本文將介紹使用JavaScript取得HTTP狀態碼的方法,並提供具體程式碼範例。一、什麼是HTTP狀態碼HTTP狀態碼是指當瀏覽器向伺服器發起請求時,服務

最佳免費AI動畫藝術生成器 最佳免費AI動畫藝術生成器 Feb 19, 2024 pm 10:50 PM

如果您渴望找到頂尖的免費AI動畫藝術生成器,您可以結束搜尋了。動漫藝術世界幾十年來一直以其獨特的角色設計、迷人的色彩和引人入勝的情節吸引觀眾。不過,創作動漫藝術需要天份、技能和耗費大量時間。然而,隨著人工智慧(AI)的不斷發展,現在你可以藉助最佳的免費AI動畫藝術生成器,無需深入了解複雜技術,就能探索動漫藝術的世界。這將為你釋放創造力提供新的可能性。什麼是人工智慧動漫藝術生成器? AI動畫藝術生成器利用複雜的演算法和機器學習技術,分析廣泛的動畫作品資料庫。透過這些演算法,系統學習並識別不同動漫風格的

See all articles