JavaScript高級程序設計(第四版)--學習記錄之迭代器與生成器(上)

什么是迭代?

迭代的意思是按照順序反復多次執行一段程序。循環是迭代機制的基礎,因為它可以指定迭代的次數,以及每次迭代要執行的操作。

迭代器模式

迭代器模式描述了一個方案,可以把有些結構稱為“可迭代對象”?,這些對象實現了正式的Iterable接口,而且可以通過迭代器Iterator消費。

迭代器是按需創建的一次性對象,每個迭代器都會關聯一個可迭代對象,而迭代器會暴露迭代其關聯可迭代對象的API。

實現Iterable接口要求同時具備兩種能力:支持迭代的自我識別能力和創建實現Iterator接口的對象的能力。

以下內置類型實現了Iterable接口:

  • 字符串
  • 數組
  • 映射
  • 集合
  • argumens對象
  • NodeList等DOM集合類型
let num = 1; 
let obj = {}; 
// 這兩種類型沒有實現迭代器工廠函數
console.log(num[Symbol.iterator]); // undefined 
console.log(obj[Symbol.iterator]); // undefined 
let str = 'abc'; 
let arr = ['a', 'b', 'c']; 
let map = new Map().set('a', 1).set('b', 2).set('c', 3); 
let set = new Set().add('a').add('b').add('c'); 
let els = document.querySelectorAll('div'); 
// 這些類型都實現了迭代器工廠函數
console.log(str[Symbol.iterator]); // f values() { [native code] } 
console.log(arr[Symbol.iterator]); // f values() { [native code] } 
console.log(map[Symbol.iterator]); // f values() { [native code] } 
console.log(set[Symbol.iterator]); // f values() { [native code] } 
console.log(els[Symbol.iterator]); // f values() { [native code] } 
// 調用這個工廠函數會生成一個迭代器
console.log(str[Symbol.iterator]()); // StringIterator {} 
console.log(arr[Symbol.iterator]()); // ArrayIterator {} 
console.log(map[Symbol.iterator]()); // MapIterator {} 
console.log(set[Symbol.iterator]()); // SetIterator {} 
console.log(els[Symbol.iterator]()); // ArrayIterator {}

接收可迭代對象的原生語言特性包括:

  • for-of循環
  • 數組解構
  • 擴展操作符
  • Array.from()
  • 創建集合
  • 創建映射
  • Promise.all()接收由期約組成的可迭代對象
  • Promise.race()接收由期約組成的可迭代對象
  • yield*操作符,在生成器中使用
let arr = ['foo', 'bar', 'baz']; 
// for-of 循環
for (let el of arr) { console.log(el); 
} 
// foo 
// bar 
// baz 
// 數組解構
let [a, b, c] = arr; 
console.log(a, b, c); // foo, bar, baz 
// 擴展操作符
let arr2 = [...arr]; 
console.log(arr2); // ['foo', 'bar', 'baz'] 
// Array.from() 
let arr3 = Array.from(arr); 
console.log(arr3); // ['foo', 'bar', 'baz'] 
// Set 構造函數
let set = new Set(arr); 
console.log(set); // Set(3) {'foo', 'bar', 'baz'} 
// Map 構造函數
let pairs = arr.map((x, i) => [x, i]); 
console.log(pairs); // [['foo', 0], ['bar', 1], ['baz', 2]] 
let map = new Map(pairs); 
console.log(map); // Map(3) { 'foo'=>0, 'bar'=>1, 'baz'=>2 } 
如果對象原型鏈上的父類實現了 Iterable 接口,那這個對象也就實現了這個接口:
class FooArray extends Array {} 
let fooArr = new FooArray('foo', 'bar', 'baz'); 
for (let el of fooArr) { console.log(el); 
} 
// foo 
// bar 
// baz

迭代器API使用next()方法在可迭代對象中遍歷數據。next()方法返回的迭代器對象IteratorResult 包含兩個屬性:done 和 value。done 是一個布爾值,表示是否還可以再次調用 next()取得下一個值;value 包含可迭代對象的下一個值(done 為false),或者undefined(done 為 true)。done: true 狀態稱為“耗盡”。

// 可迭代對象
let arr = ['foo', 'bar']; 
// 迭代器工廠函數
console.log(arr[Symbol.iterator]); // f values() { [native code] } 
// 迭代器
let iter = arr[Symbol.iterator](); 
console.log(iter); // ArrayIterator {} 
// 執行迭代
console.log(iter.next()); // { done: false, value: 'foo' } 
console.log(iter.next()); // { done: false, value: 'bar' } 
console.log(iter.next()); // { done: true, value: undefined }

提前終止迭代器的方式:

  • for-of 循環通過 break continue return throw 提前退出
  • 解構操作并未消費所有值
    class Counter { constructor(limit) { this.limit = limit; } [Symbol.iterator]() { let count = 1, limit = this.limit; return { next() { if (count <= limit) { return { done: false, value: count++ }; } else { return { done: true }; } }, return() { console.log('Exiting early'); return { done: true }; } }; } 
    } 
    let counter1 = new Counter(5); 
    for (let i of counter1) { if (i > 2) { break; } console.log(i); 
    }
    // 1 
    // 2 
    // Exiting early 
    let counter2 = new Counter(5); 
    try { for (let i of counter2) { if (i > 2) { throw 'err'; } console.log(i); } 
    } catch(e) {} 
    // 1 
    // 2 
    // Exiting early 
    let counter3 = new Counter(5); 
    let [a, b] = counter3; 
    // Exiting early

    并非所有迭代器都是可關閉的。要知道某個迭代器是否可關閉,可以測試這個迭代器實例的 return 屬性是不是函數對象。不過,僅僅給一個不可關閉的迭代器增加這個方法并不能讓它變成可關閉的。這是因為調用 return()不會強制迭代器進入關閉狀態。即便此,
    return() 方法還是會被調用。
    let a = [1, 2, 3, 4, 5]; 
    let iter = a[Symbol.iterator](); 
    iter.return = function() { console.log('Exiting early'); return { done: true };
    }; 
    for (let i of iter) { console.log(i); if (i > 2) { break } 
    } 
    // 1 
    // 2 
    // 3 
    // 提前退出
    for (let i of iter) { console.log(i); 
    } 
    // 4 
    // 5

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/36984.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/36984.shtml
英文地址,請注明出處:http://en.pswp.cn/web/36984.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于 DJYOS 的 HMI 場景研究:探索智能生活的無限可能

引言&#xff1a; 在當今數字化時代&#xff0c;人機界面&#xff08;HMI&#xff09;技術的發展正深刻改變著我們的生活方式。DJYOS 作為一款先進的操作系統&#xff0c;為 HMI 產品的開發提供了強大的支持。本文將深入探討基于 DJYOS 的 HMI 場景&#xff0c;展示其在智能家…

通過rediss實現用戶菜單智能推薦

本人用的框架 SpringCloud redisOauth2Security 前言&#xff1a; 整體使用過濾器的思想&#xff0c;獲取Request&#xff0c;然后從數據庫查到菜單名稱和路由以及計算點擊次數&#xff0c;最后以list的形式存在redis&#xff0c;設計定時任務&#xff0c;在一定時間后&#x…

Search for documents with similar texts

題意&#xff1a;搜索具有相似文本的文檔 問題背景&#xff1a; I have a document with three attributes: tags, location, and text. 我有一份文檔&#xff0c;包含三個屬性&#xff1a;標簽、位置和文本。 Currently, I am indexing all of them using LangChain/pgvecto…

快速了解《大模型賦能下的AI2.0數字人平臺》白皮書

在生成式AI和大模型的賦能下&#xff0c;數字人迎來AI 2.0時代。它能否成為每個人的“數字分身”&#xff0c;轉化為新型的AI勞動力工具&#xff1f;商湯科技與上海市人工智能技術協會、零壹智庫、增強現實核心技術產業聯盟聯合發布《大模型賦能下的AI 2.0數字人平臺》。《白皮…

Kubernetes面試整理-PersistentVolumes和PersistentVolumeClaims的使用和配置

在 Kubernetes 中,PersistentVolumes (PV) 和 PersistentVolumeClaims (PVC) 提供了一種分離存儲和使用存儲的機制。PV 是集群中存儲資源的抽象表示,而 PVC 是用戶對存儲資源的請求。通過這種機制,用戶可以動態地申請和管理存儲資源。 PersistentVolumes (PV) PersistentVol…

【D3.js in Action 3 精譯】1.2.2 可縮放矢量圖形(二)

當前內容所在位置 第一部分 D3.js 基礎知識 第一章 D3.js 簡介 1.1 何為 D3.js&#xff1f;1.2 D3 生態系統——入門須知 1.2.1 HTML 與 DOM1.2.2 SVG - 可縮放矢量圖形 ?? 第一部分【第二部分】??第三部分&#xff08;精譯中 ?&#xff09; 1.2.3 Canvas 與 WebGL&#x…

自動化任務:在IPython中創建和運行腳本

在數據科學和編程中&#xff0c;自動化任務是提高效率的關鍵。IPython提供了多種方法來創建和運行腳本&#xff0c;使得重復性任務可以被輕松自動化。本文將介紹如何在IPython中創建和運行腳本&#xff0c;幫助你更高效地完成工作。 1. 創建和保存IPython腳本 使用文本編輯器…

Spring Boot 中的微服務監控與管理

微服務的概述 微服務架構的優點和挑戰 優點: 靈活性和可擴展性:微服務架構允許每個服務單獨部署和擴展,這使得系統可以更靈活地適應不同的業務需求和負載變化。 使團隊更加聚焦:每個微服務都有明確的職責,這使得開發團隊可以更加聚焦,專注于開發他們的服務。 技術和框…

讀AI新生:破解人機共存密碼筆記16對人工智能的治理

1. 愚蠢的、情緒化的人類 1.1. 與完美理性所設定的不可企及的標準相比&#xff0c;我們都是極其愚蠢的&#xff0c;我們受制于各種情緒的起伏&#xff0c;這些情緒在很大程度上支配著我們的行為 1.2. 為了充分了解人類的認知&#xff0c;我們&#xff08;或者更確切地說&…

簡易跨平臺上傳文件,前后端demo

前端文件 <!DOCTYPE html> <html> <head><title>文件上傳</title> </head> <body> <h1>文件上傳1-相對慢&#xff0c;需要等待本地選擇的文件全部上傳完成后&#xff0c;服務器再保存</h1> <form id"uploadForm…

ORA-01775: 同義詞的循環鏈問題

一、問題描述 ORA-01775: 同義詞的循環鏈問題 二、 原因分析 同義詞對應的對象&#xff08;表等&#xff09;已刪除&#xff0c;不存在了。 可能原因&#xff1a; 刪除數據庫對象&#xff0c;但是忘記刪除同義詞。刪除一個用戶&#xff0c;但忘記刪除此用戶中相關的同義詞…

@Param參數

Param參數 當方法參數大于兩個的時候必須傳遞&#xff0c;只有一個的時候可以不傳。大于兩個的時候也可以用#{arg0}和#{arg1}。。。來取值 Param&#xff08;&#xff09;括號里面的值對應sql語句中 # {} 里面的值 看AI的解釋

模版方法模式詳解:使用和實現的指南

目錄 模版方法模式模版方法模式結構模版方法模式適合應用場景模版方法模式優缺點練手題目題目描述輸入描述輸出描述題解 模版方法模式 模板方法模式是一種行為設計模式&#xff0c; 它在超類中定義了一個算法的框架&#xff0c; 允許子類在不修改結構的情況下重寫算法的特定步…

《昇思25天學習打卡營第3天|張量 Tensor》

文章目錄 前言&#xff1a;今日所學&#xff1a;1. 創建張量2. 張量的屬性3.張量索引與運算4. NumPy與Tensor的轉換5. 稀疏張量 前言&#xff1a; 張量&#xff1f;張亮&#xff1f;張量是什么&#xff1f; 張量是一個可以用來表示在一些矢量、標量和其他張量之間的線性關系的…

高并發部署:基于 Gunicorn、Flask 和 Docker

一、準備工作 確保已經安裝以下軟件&#xff1a; DockerDocker ComposePython 3.x 二、創建 Flask 應用 首先&#xff0c;創建一個簡單的 Flask 應用。創建一個新的目錄并在其中創建以下文件&#xff1a; 1. app.py python fromflask importFlask, jsonifyapp Flask(__…

leetcode 第133場雙周賽 100333.統計逆序對的數目【計數dp/滾動數組/前綴和優化】

分析&#xff1a; 先考慮如下問題。 求長度為n&#xff0c;逆序對為m的排列數量。 可以考慮dp&#xff0c;dp[i][j]定義為長度為i&#xff0c;逆序對為j的排列數量。 dp[1][0] 1; //枚舉排列長度&#xff0c;或者認為枚舉當前需要插到長度為i-1的排列中的數字 for(int i 1…

OpenAI封殺不支持地區API:違規封號,7月9日生效

OpenAI 在檢測用戶使用其 API 的地區后&#xff0c;提示所有不支持位置的用戶 昨晚&#xff0c;很多大模型應用的開發者、程序員都收到了 OpenAI 的警告信&#xff0c;心里一驚。 OpenAI 在檢測用戶使用其 API 的地區后&#xff0c;提示所有不支持位置的用戶&#xff1a;即將封…

冒泡排序、選擇排序、插入排序~java版

1、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序的基本思想是多次遍歷待排序序列&#xff0c;每次遍歷時兩兩比較相鄰元素&#xff0c;如果順序不對則交換&#xff0c;直到整個序列有序為止。 public class BubbleSort {public static void bubbleSort(int[] arr) …

圖書管理系統(附源碼)

前言&#xff1a;前面一起和小伙伴們學習了較為完整的Java語法體系&#xff0c;那么本篇將運用這些知識連串在一起實現圖書管理系統。 目錄 一、總體設計 二、書籍與書架 書籍&#xff08;Book&#xff09; 書架&#xff08;Booklist&#xff09; 三、對圖書的相關操作 I…

已解決問題 | 該擴展程序未列在 Chrome 網上應用店中,并可能是在您不知情的情況下添加的

在Chrome瀏覽器中&#xff0c;如果你看到“該擴展程序未列在 Chrome 網上應用店中&#xff0c;并可能是在您不知情的情況下添加的”這樣的提示&#xff0c;通常是因為該擴展程序沒有通過Chrome網上應用店進行安裝。以下是解決這個問題的步驟&#xff1a; 解決辦法&#xff1a;…