摘要:有兩個協議可迭代協議和迭代器協議。為了變成可迭代對象,一個對象必須實現或者它原型鏈的某個對象必須有一個名字是的屬性迭代器協議該迭代器協議定義了一種標準的方式來產生一個有限或無限序列的值。
ECMAScript 2015的幾個補充,并不是新的內置或語法,而是協議。這些協議可以被任何遵循某些約定的對象來實現。可迭代協議
有兩個協議:可迭代協議和迭代器協議。
可迭代協議允許 JavaScript 對象去定義或定制它們的迭代行為, 例如(定義)在一個 for..of 結構中什么值可以被循環(得到)。一些內置類型都是內置的可迭代對象并且有默認的迭代行為, 比如 Array or Map, 另一些類型則不是 (比如Object) 。
Iterator 接口的目的,就是為所有數據結構,提供了一種統一的訪問機制,即for...of循環(詳見下文)。當使用for...of循環遍歷某種數據結構時,該循環會自動去尋找 Iterator 接口,調用Symbol.iterator方法,返回該對象的默認遍歷器。
ES6 規定,默認的 Iterator 接口部署在數據結構的Symbol.iterator屬性,或者說,一個數據結構只要具有Symbol.iterator屬性,就可以認為是“可迭代的”(iterable)。Symbol.iterator屬性本身是一個函數,就是當前數據結構默認的遍歷器生成函數。執行這個函數,就會返回一個遍歷器。
為了變成可迭代對象, 一個對象必須實現(或者它原型鏈的某個對象)必須有一個名字是 Symbol.iterator 的屬性:
迭代器協議該迭代器協議定義了一種標準的方式來產生一個有限或無限序列的值。
JavaScript 原有的表示“集合”的數據結構,主要是數組(Array)和對象(Object),ES6 又添加了Map和Set。這樣就有了四種數據集合,用戶還可以組合使用它們,定義自己的數據結構,比如數組的成員是Map,Map的成員是對象。這樣就需要一種統一的接口機制,來處理所有不同的數據結構。
迭代器(Iterator)就是這樣一種機制。它是一種接口,為各種不同的數據結構提供統一的訪問機制。任何數據結構只要部署 Iterator 接口,就可以完成遍歷操作(即依次處理該數據結構的所有成員)。
Iterator 的作用有三個:一是為各種數據結構,提供一個統一的、簡便的訪問接口;二是使得數據結構的成員能夠按某種次序排列;三是 ES6 創造了一種新的遍歷命令for...of循環,Iterator 接口主要供for...of消費。
Iterator 的遍歷過程是這樣的。
創建一個指針對象,指向當前數據結構的起始位置。也就是說,遍歷器對象本質上,就是一個指針對象。
第一次調用指針對象的next方法,可以將指針指向數據結構的第一個成員。
第二次調用指針對象的next方法,指針就指向數據結構的第二個成員。
不斷調用指針對象的next方法,直到它指向數據結構的結束位置。
每一次調用next方法,都會返回數據結構的當前成員的信息。具體來說,就是返回一個包含value和done兩個屬性的對象。其中,value屬性是當前成員的值,done屬性是一個布爾值,表示遍歷是否結束。
var someString = "hi"; typeof someString[Symbol.iterator]; // "function" var iterator = someString[Symbol.iterator](); iterator + ""; // "[object String Iterator]" iterator.next() // { value: "h", done: false } iterator.next(); // { value: "i", done: false } iterator.next(); // { value: undefined, done: true }
原生具備 Iterator 接口的數據結構如下。
Array
Map
Set
String
TypedArray
函數的 arguments 對象
NodeList 對象
注意對象是不具備 Iterator 接口的,一個對象如果要具備可被for...of循環調用的 Iterator 接口,就必須在Symbol.iterator的屬性上部署遍歷器生成方法(原型鏈上的對象具有該方法也可)。
調用 Iterator 接口的場合有一些場合會默認調用 Iterator 接口(即Symbol.iterator方法),除了下文會介紹的for...of循環,解構賦值, 擴展運算符其實也會調用默認的Iterator 接口。
實際上,這提供了一種簡便機制,可以將任何部署了 Iterator 接口的數據結構,轉為數組。也就是說,只要某個數據結構部署了 Iterator 接口,就可以對它使用擴展運算符,將其轉為數組。
由于數組的遍歷會調用遍歷器接口,所以任何接受數組作為參數的場合,其實都調用了遍歷器接口。下面是一些例子。
for...of
Array.from()
Map(), Set(), WeakMap(), WeakSet()(比如new Map([["a",1],["b",2]]))
Promise.all()
Promise.race()
for...offor...of 循環是最新添加到 JavaScript 循環系列中的循環。
它結合了其兄弟循環形式 for 循環和 for...in 循環的優勢,可以循環任何可迭代(也就是遵守可迭代協議)類型的數據。默認情況下,包含以下數據類型:String、Array、Map 和 Set,注意不包含 Object 數據類型(即 {})。默認情況下,對象不可迭代。
在研究 for...of 循環之前,先快速了解下其他 for 循環,看看它們有哪些不足之處。
for 循環for 循環的最大缺點是需要跟蹤計數器和退出條件。我們使用變量 i 作為計數器來跟蹤循環并訪問數組中的值。我們還使用 Array.length 來判斷循環的退出條件。
雖然 for 循環在循環數組時的確具有優勢,但是某些數據結構不是數組,因此并非始終適合使用 loop 循環。
for...in 循環for...in 循環改善了 for 循環的不足之處,它消除了計數器邏輯和退出條件。但是依然需要使用 index 來訪問數組的值.
此外,當你需要向數組中添加額外的方法(或另一個對象)時,for...in 循環會帶來很大的麻煩。因為 for...in 循環循環訪問所有可枚舉的屬性,意味著如果向數組的原型中添加任何其他屬性,這些屬性也會出現在循環中。這就是為何在循環訪問數組時,不建議使用 for...in 循環。
注意: forEach 循環 是另一種形式的 JavaScript 循環。但是,forEach() 實際上是數組方法,因此只能用在數組中。也無法停止或退出 forEach 循環。如果希望你的循環中出現這種行為,則需要使用基本的 for 循環。for...of 循環
for...of 循環用于循環訪問任何可迭代的數據類型。
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (const digit of digits) { console.log(digit); }
可以隨時停止或退出 for...of 循環。
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (const digit of digits) { if (digit % 2 === 0) { continue; } console.log(digit); //1,3,5,7,9 }
不用擔心向對象中添加新的屬性。for...of 循環將只循環訪問對象中的值。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/92312.html
摘要:迭代器模式迭代器模式是指提供一種方法順序訪問一個聚合對象中的各個元素,而不需要暴露該對象的內部表示。可迭代協議和迭代器協議。生成器函數是可以作為迭代器工廠的函數,當它被執行時會返回一個新的對象,該對象符合可迭代協議和迭代器協議。 迭代器模式 迭代器模式是指提供一種方法順序訪問一個聚合對象中的各個元素,而不需要暴露該對象的內部表示。 迭代器分為內部迭代器和外部迭代器。內部迭代器只需一次初...
摘要:基本原理解構是提供的語法糖,其實內在是針對可迭代對象的接口,通過遍歷器按順序獲取對應的值進行賦值。屬性值返回一個對象的無參函數,被返回對象符合迭代器協議。迭代器協議定義了標準的方式來產生一個有限或無限序列值。 更多系列文章請看 1、基本語法 1.1、數組 // 基礎類型解構 let [a, b, c] = [1, 2, 3] console.log(a, b, c) // 1, 2, ...
摘要:本文從使用對數組進行遍歷開始說起,粗略對比使用進行遍歷的差異,并由此引入中可迭代對象迭代器的概念,并對其進行粗略介紹。說到這里,就繼續說一下迭代器關閉的情況了。確實,符合可迭代協議和迭代器協議的。 本文從使用 forEach 對數組進行遍歷開始說起,粗略對比使用 forEach , for...in , for...of 進行遍歷的差異,并由此引入 ES6 中 可迭代對象/迭代器 的概...
摘要:需要說明的是,每次執行完函數之后,都會返回一個對象這個返回值有兩個屬性和,對象通過這個返回值來告訴外界函數的執行情況。函數的返回值變成這樣可以發現的值變為了,因為函數已經執行完了。在規范中,新增了兩個協議可迭代協議和迭代器協議。 Koa是最近比較火的一款基于Node的web開發框架。說他是一個框架,其實他更像是一個函數庫,通過某種思想(或者說某種約定),將眾多的中間件聯系在一起,從而提...
摘要:理解迭代對象迭代器生成器后端掘金本文源自作者的一篇博文,原文是,俺寫的這篇文章是按照自己的理解做的參考翻譯。比較的是兩個對象的內容是后端掘金黑魔法之協程異步后端掘金本文為作者原創,轉載請先與作者聯系。 完全理解關鍵字with與上下文管理器 - 掘金如果你有閱讀源碼的習慣,可能會看到一些優秀的代碼經常出現帶有 with 關鍵字的語句,它通常用在什么場景呢?今天就來說說 with 和 上下...
閱讀 996·2023-04-26 01:47
閱讀 1680·2021-11-18 13:19
閱讀 2048·2019-08-30 15:44
閱讀 659·2019-08-30 15:44
閱讀 2301·2019-08-30 15:44
閱讀 1239·2019-08-30 14:06
閱讀 1428·2019-08-30 12:59
閱讀 1906·2019-08-29 12:49