遍歷器Iterator存取資料集合的統一介面的方法
這篇文章跟大家介紹的內容是關於遍歷器Iterator存取資料集合的統一介面的方法,有著一定的參考價值,有需要的朋友可以參考一下。
導語
遍歷器Iterator
是ES6為存取資料集合提供的統一介面。任何內部部署了遍歷器介面的資料集合,對於使用者來說,都可以使用相同方式取得到對應的資料結構。如果使用的是最新版Chrome
瀏覽器,那麼你要知道——我們所熟悉的數組小姐,已悄悄的打開了另一扇可抵達她心扉的小徑。
1 正題
某個資料集合部署了Iterator
接口,是指其Symbol.iterator
屬性指向一個能傳回Iterator
介面的函數。任何預設使用遍歷器存取資料集合的方法,都會呼叫此屬性以獲得遍歷器對象,再按照設定的順序依次存取該資料結構的成員(關於Symbol.iterator
請看最後一節的延伸閱讀)。例如原生數組的遍歷器為[][Symbol.iterator]
,也可以直接透過其建構子的原型取得Array.prototype[Symbol.iterator]
。
1.1 基本行為
呼叫Iterator
介面會傳回一個新的遍歷器物件(指針對象)。
物件中必然有next
方法,用來存取下一個資料成員。指標初始時指向目前資料結構的起始位置。
第一次呼叫物件的next
方法,指標指向資料結構的第一個成員。
第二次呼叫物件的next
方法,指標指向資料結構的第二個成員。
不斷的呼叫物件的next
方法,直到它指向資料結構的結束位置。
每次呼叫next
方法,都會傳回相同的資料結構:{ value, done }
。
其中value
表示目前指向成員的值,沒有則為undefined
。
其中done
是一個布林值,表示遍歷是否結束,結束為true
,否則false
。
遍歷器介面的標準十分簡潔,不提供諸如:操作內部指標、判斷是否有值等等方法。只需要一直不斷的呼叫next
方法,當done
為false
時取得當時的value
,done
為true
時停止即可。第一次接觸遍歷器的行為模式是在2016的冬天,那時底蘊不夠雞毛也沒長全,理解不了簡潔性的適用與強大。直到現在——在即將打包被迫離開公司的前夕才驀然的覺醒。多麼痛的領悟。
let iterator = [1, 2, 3][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}
1.2 簡單實作
面向不同的資料結構,有不同的遍歷器實作方法,我們簡單的實作下數組的遍歷器方法。
let res = null; let iterator = myIterator([3, 7]); console.log( iterator.next() ); // {value: 3, done: false} console.log( iterator.next() ); // {value: 7, done: false} console.log( iterator.next() ); // {value: undefined, done: true} function myIterator(array = []) { let index = 0; return { next() { return index < array.length ? { value: array[index++], done: false } : { value: undefined, done: true }; } }; }
1.3 return & throw
除了為遍歷器物件部署next
方法,還可以有return
和throw
方法。其中return
方法會在提前退出for of
迴圈時(通常是因為出錯,或觸發了break
語句)被呼叫。而throw
方法主要是配合Generator
函數使用,一般的遍歷器物件用不到這個方法,所以不予介紹。
let obj = { [Symbol.iterator]() { let index = 0; let array = [1, 2, 3]; return { next() { return index < array.length ? { value: array[index++], done: false } : { value: undefined, done: true }; }, return() { console.log('Trigger return.'); return {}; } }; } }; for (let v of obj) { console.log(v); // 打印出:1, 2, 3,没触发 return 函数。 } for (let v of obj) { if (v === 2) break; console.log(v); // 打印出:1,之后触发 return 函数。 } for (let v of obj) { if (v === 3) break; console.log(v); // 打印出:1, 2,之后触发 return 函数。 } for (let v of obj) { if (v === 4) break; console.log(v); // 打印出:1, 2, 3,没触发 return 函数。 } for (let v of obj) { if (v === 2) throw Error('error'); console.log(v); // 打印出:1,之后触发 return 函数,并报错停止执行。 }
2 原生支援
2.1 預設持有遍歷器
原生預設持有遍歷器介面的資料結構有:
基本型別:Array
, Set
, Map
(四個基本資料集合:Array
, Object
, Set
# 和Map
)。
類別陣列物件:arguments
, NodeList
, String
。
let iterator = '123'[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}
遍歷器與先前的遍歷方法
一個資料集合擁有遍歷器接口,並不意味著所有遍歷它的方法都是使用此接口。實際上,只有ES6新增的幾種方式和某些方法會使用,以下會有介紹。以陣列來說,對其使用for
和for of
雖然可存取到相同的成員,但是實際的操作方式卻不同。
// 改变数组默认的遍历器接口。 Array.prototype[Symbol.iterator] = function () { let index = 0; let array = this; console.log('Use iterator'); return { next() { return index < array.length ? { value: array[index++], done: false } : { value: undefined, done: true }; } } }; let arr = [1, 2]; for (let v of arr) { console.log(v); // 打印出 Use iterator, 1, 2。 } for (let i = 0; i < arr.length; i++) { console.log(arr[i]); // 打印出 1, 2。 } arr.forEach(d => { console.log(d); // 打印出 1, 2。 });
物件沒有預設的遍歷器介面
為什麼物件沒有預設的遍歷器介面?這要從兩方面說明。一為遍歷器是種線性處理結構,對於任何非線性的資料結構,部署了遍歷器接口,就等於部署一種線性轉換。二是物件本來就是一個無序的集合,如果希望其有序,可以用Map
來代替。這即是各有其長,各安其職。屎殼郎如果不滾糞球而去採蜜,那,呃,花妹妹可能就遭殃咯。
自行生成的类数组对象(拥有length
属性),不具备遍历器接口。这与String
等原生类数组对象不同,毕竟人家是亲生的,一出生就含着金钥匙(也不怕误吞)。不过我们可以将数组的遍历器接口直接应用于自行生成的类数组对象,简单有效无副作用。
let obj = { 0: 'a', 1: 'b', length: 2, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; let iterator = obj[Symbol.iterator](); console.log( iterator.next() ); // {value: "a", done: false} console.log( iterator.next() ); // {value: "b", done: false} console.log( iterator.next() ); // {value: undefined, done: true}
为对象添加遍历器接口,也不影响之前不使用遍历器的方法,比如for in
, Object.keys
等等(两者不等同)。
let obj = { 0: 'a', 1: 'b', length: 2, [Symbol.iterator]: Array.prototype[Symbol.iterator] }; console.log( Object.keys(obj) ); // ["0", "1", "length"] for (let v of obj) { console.log(v); // 依次打印出:"a", "b"。 } for (let k in obj) { console.log(k); // 依次打印出:"0", "1", "length"。 }
2.2 默认调用遍历器
for of for of
是专门用来消费遍历器的,其遍历的是键值(for in
遍历的是键名)。
for (let v of [1, 2, 3]) { console.log(v); // 依次打印出:1, 2, 3。 }
扩展运算符
无论是解构赋值或扩展运算都是默认调用遍历器的。
let [...a] = [3, 2, 1]; // [3, 2, 1] let b = [...[3, 2, 1]]; // [3, 2, 1]
yield*
在Generator
函数中有yield*
命令,如果其后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。
for (let v of G()) { console.log(v); // 依次打印出:1, 2, 3, 4, 5 } function* G() { yield 1; yield* [2,3,4]; yield 5; }
其它场合
有些接受数组作为参数的函数,会默认使用数组的遍历器接口,所以也等同于默认调用。比如Array.from()
, Promise.all()
。
相关推荐:
以上是遍歷器Iterator存取資料集合的統一介面的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

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

我們在電腦組裝的過程中,安裝過程雖然簡單,不過往往都是在接線上遇到問題,經常有裝機用戶誤將CPU散熱器的供電線插到了SYS_FAN上,雖然風扇可以轉動,不過在開機可能會有F1報錯“CPUFanError”,同時也導致了CPU散熱器無法智慧調速。下面裝機之家分享一下電腦主機板上CPU_FAN、SYS_FAN、CHA_FAN、CPU_OPT介面知識科普。電腦主機板上CPU_FAN、SYS_FAN、CHA_FAN、CPU_OPT介面知識科普1、CPU_FANCPU_FAN是CPU散熱器專用接口,12V工作

Go語言作為一門現代化的、高效的程式語言,擁有豐富的程式設計範式和設計模式可以幫助開發者編寫高品質、可維護的程式碼。本文將介紹Go語言中常見的程式設計範式和設計模式,並提供具體的程式碼範例。 1.物件導向程式設計在Go語言中,可以使用結構體和方法實現物件導向程式設計。透過定義結構體和給結構體綁定方法,可以實現資料封裝和行為綁定在一起的物件導向特性。 packagemaini

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

PHP介面簡介及其定義方式PHP是一種廣泛應用於Web開發的開源腳本語言,具有靈活、簡單、強大等特性。在PHP中,介面(interface)是一種定義多個類別之間公共方法的工具,實現了多態性,讓程式碼更加靈活和可重複使用。本文將介紹PHP介面的概念及其定義方式,同時提供具體的程式碼範例展示其用法。 1.PHP介面概念介面在物件導向程式設計中扮演著重要的角色,定義了類別應

介面和抽象類別在設計模式中用於解耦和可擴展性。介面定義方法簽名,抽象類別提供部分實現,子類別必須實作未實現的方法。在策略模式中,介面用於定義演算法,抽象類別或具體類別提供實現,允許動態切換演算法。在觀察者模式中,介面用於定義觀察者行為,抽象類別或具體類別用於訂閱和發布通知。在適配器模式中,介面用於適應現有類,抽象類或具體類可實現相容接口,允許與原有程式碼互動。

在前端開發面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎、JavaScript基礎、框架和函式庫、專案經驗、演算法和資料結構、效能最佳化、跨域請求、前端工程化、設計模式以及新技術和趨勢。面試官的問題旨在評估候選人的技術技能、專案經驗以及對行業趨勢的理解。因此,應試者應充分準備這些方面,以展現自己的能力和專業知識。

介面和抽象類別用於建立可擴展的PHP程式碼,它們之間存在以下關鍵差異:介面透過實作強制執行,而抽象類別透過繼承強制執行。介面不能包含具體方法,而抽象類別可以。一個類別可以實作多個接口,但只能從一個抽象類別繼承。介面不能實例化,而抽象類別可以。
