ES6 - Iterator迭代器

一锤悄、Iterator

1.Iterator(迭代器)的概念

遍歷器(Iterator) 是一種用來處理所有不同的數(shù)據(jù)結(jié)構(gòu)的機(jī)制。它是一種接口嘉抒,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪問機(jī)制零聚。任何數(shù)據(jù)結(jié)構(gòu)只要部署 Iterator 接口,就可以完成遍歷操作(即依次處理該數(shù)據(jù)結(jié)構(gòu)的所有成員)。

JavaScript 表示“集合”的數(shù)據(jù)結(jié)構(gòu)
  • Array
  • Object
  • Map (ES6新增)
  • Set (ES6新增)
Iterator 的作用
  • 為各種數(shù)據(jù)結(jié)構(gòu)隶症,提供一個(gè)統(tǒng)一的政模、簡(jiǎn)便的訪問接口;
  • 使得數(shù)據(jù)結(jié)構(gòu)的成員能夠按某種次序排列蚂会;
  • ES6 創(chuàng)造了一種新的遍歷命令 for...of 循環(huán)淋样,Iterator 接口主要供 for...of 消費(fèi)。
Iterator 的遍歷過程
  • 創(chuàng)建一個(gè)指針對(duì)象胁住,指向當(dāng)前數(shù)據(jù)結(jié)構(gòu)的起始位置趁猴。也就是說,遍歷器對(duì)象本質(zhì)上彪见,就是一個(gè)指針對(duì)象儡司。

  • 第一次調(diào)用指針對(duì)象的 next 方法,可以將指針指向數(shù)據(jù)結(jié)構(gòu)的第一個(gè)成員余指。

  • 第二次調(diào)用指針對(duì)象的 next 方法捕犬,指針就指向數(shù)據(jù)結(jié)構(gòu)的第二個(gè)成員。

  • 不斷調(diào)用指針對(duì)象的 next 方法酵镜,直到它指向數(shù)據(jù)結(jié)構(gòu)的結(jié)束位置或听。

每一次調(diào)用 next 方法,都會(huì)返回?cái)?shù)據(jù)結(jié)構(gòu)的當(dāng)前成員的信息笋婿。具體來說,就是返回一個(gè)包含 valuedone 兩個(gè)屬性的對(duì)象顿颅。其中:

  • value 屬性:當(dāng)前成員的值
  • done 屬性:一個(gè)布爾值缸濒,表示遍歷是否結(jié)束。

2.迭代器協(xié)議

迭代器協(xié)議 定義了產(chǎn)生一系列值(無論是有限個(gè)還是無限個(gè))的標(biāo)準(zhǔn)方式粱腻。當(dāng)值為有限個(gè)時(shí)庇配,所有的值都被迭代完畢后,則會(huì)返回一個(gè)默認(rèn)返回值绍些。

只有實(shí)現(xiàn)了一個(gè)擁有以下語義的 next() 方法捞慌,一個(gè)對(duì)象才能成為迭代器:

  • next()方法:是一個(gè)無參數(shù)函數(shù),返回一個(gè)擁有 donevalue 兩個(gè)屬性的對(duì)象柬批。

  • done(boolean):如果迭代器可以產(chǎn)生序列中的下一個(gè)值啸澡,則為 false 。如果迭代器已將序列迭代完畢氮帐,則為 true 嗅虏。這種情況下,value 是可選的上沐,如果它依然存在皮服,即為迭代結(jié)束之后的默認(rèn)返回值。

  • value:迭代器返回的任何 JavaScript 值。done 為 true 時(shí)可省略龄广。

  • 注意next() 方法必須返回一個(gè)對(duì)象硫眯,該對(duì)象應(yīng)當(dāng)有兩個(gè)屬性: donevalue,如果返回了一個(gè)非對(duì)象值(比如 falseundefined)择同,則會(huì)拋出一個(gè) TypeError 異常("iterator.next() returned a non-object value")两入。

3.可迭代協(xié)議

可迭代協(xié)議 允許 JavaScript 對(duì)象定義或定制它們的迭代行為,例如奠衔,在一個(gè) for..of 結(jié)構(gòu)中谆刨,哪些值可以被遍歷到。一些內(nèi)置類型同時(shí)是內(nèi)置可迭代對(duì)象或者 Map 而其他內(nèi)置類型則不是(比如 Object)归斤。

要成為可迭代對(duì)象痊夭, 一個(gè)對(duì)象必須實(shí)現(xiàn) @@iterator 方法。

  • [Symbol.iterator] :返回一個(gè)符合 迭代器協(xié)議 的對(duì)象的無參數(shù)函數(shù)脏里。

當(dāng)一個(gè)對(duì)象需要被迭代的時(shí)候(比如被置入一個(gè) for...of 循環(huán)時(shí))她我,首先,會(huì)不帶參數(shù)調(diào)用它的 @@iterator 方法迫横,然后使用此方法返回的 迭代器 獲得要迭代的值番舆。

值得注意的是調(diào)用此零個(gè)參數(shù)函數(shù)時(shí),它將作為對(duì)可迭代對(duì)象的方法進(jìn)行調(diào)用矾踱。 因此恨狈,在函數(shù)內(nèi)部,this 關(guān)鍵字可用于訪問可迭代對(duì)象的屬性呛讲,以決定在迭代過程中提供什么禾怠。

此函數(shù)可以是普通函數(shù),也可以是生成器函數(shù)贝搁,以便在調(diào)用時(shí)返回迭代器對(duì)象吗氏。 在此生成器函數(shù)的內(nèi)部,可以使用 yield 提供每個(gè)條目雷逆。

4.實(shí)現(xiàn)一個(gè)滿足迭代器協(xié)議與可迭代協(xié)議的對(duì)象

var letters= {
  cursor: 0,
  next () {
    const actions = ['A', 'B', 'C', 'D']
    if (this.cursor > 7) {
      return {
        done: true
      }
    }
    return {
      done: false,
      value: actions[this.cursor++ % actions.length]
    }
  },
  [Symbol.iterator]: function () {
    return this
  }
}

// 實(shí)現(xiàn)后可用for…of遍歷

for (let item of letters) {
  console.log('item:::', item) // done 為 true 時(shí) 不執(zhí)行value中的語句
}
// 輸出結(jié)果:
// item::: A
// item::: B
// item::: C
// item::: D
// item::: A
// item::: B
// item::: C
// item::: D

5.為什么需要2個(gè)協(xié)議

  • 因?yàn)椴豢赡苤酪粋€(gè)特定的對(duì)象是否實(shí)現(xiàn)了迭代器協(xié)議弦讽,然而創(chuàng)造一個(gè)同時(shí)滿足迭代器協(xié)議和可迭代協(xié)議的對(duì)象是很容易的(就像上面的栗子所示)。這樣做允許一個(gè)迭代器能被不同希望迭代的語法方式所使用膀哲。 因此往产,很少只實(shí)現(xiàn)迭代器協(xié)議而不實(shí)現(xiàn)可迭代協(xié)議。

6.實(shí)現(xiàn)了迭代器協(xié)議與可迭代協(xié)議的語法或特性

  • Array
  • Set
  • Map
  • generator

7.使用了迭代器協(xié)議與可迭代協(xié)議的語法或特性

  • for...of...
  • ...
  • Array.from()

二等太、參考資料

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末捂齐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缩抡,更是在濱河造成了極大的恐慌奠宜,老刑警劉巖包颁,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異压真,居然都是意外死亡娩嚼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門滴肿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來岳悟,“玉大人,你說我怎么就攤上這事泼差」笊伲” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵堆缘,是天一觀的道長(zhǎng)滔灶。 經(jīng)常有香客問我,道長(zhǎng)吼肥,這世上最難降的妖魔是什么录平? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮缀皱,結(jié)果婚禮上斗这,老公的妹妹穿的比我還像新娘。我一直安慰自己啤斗,他們只是感情好表箭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著钮莲,像睡著了一般燃逻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上臂痕,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音猿涨,去河邊找鬼握童。 笑死,一個(gè)胖子當(dāng)著我的面吹牛叛赚,可吹牛的內(nèi)容都是我干的澡绩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼俺附,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼肥卡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起事镣,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤步鉴,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體氛琢,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡喊递,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了阳似。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片骚勘。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖撮奏,靈堂內(nèi)的尸體忽然破棺而出俏讹,到底是詐尸還是另有隱情,我是刑警寧澤畜吊,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布泽疆,位于F島的核電站,受9級(jí)特大地震影響定拟,放射性物質(zhì)發(fā)生泄漏于微。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一青自、第九天 我趴在偏房一處隱蔽的房頂上張望株依。 院中可真熱鬧,春花似錦延窜、人聲如沸恋腕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荠藤。三九已至,卻和暖如春获高,著一層夾襖步出監(jiān)牢的瞬間哈肖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工念秧, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留淤井,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓摊趾,卻偏偏與公主長(zhǎng)得像币狠,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子砾层,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348