小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

JavaScript迭代器的含義

 好程序員IT 2019-07-19

什么是迭代器

  迭代器就是為實現(xiàn)對不同集合進行統(tǒng)一遍歷操作的一種機制,只要給需要遍歷的數(shù)據(jù)結構部署Iterator接口,通過調用該接口,或者使用消耗該接口的API實現(xiàn)遍歷操作。

  迭代器模式

  在接觸迭代器之前,一起先了解什么是迭代器模式,回想一下我們生活中的事例。我們在參觀景區(qū)需要買門票的時候,售票員需要做的事情,他會對排隊購票的每一個人依次進行售票,對普通成人,對學生,對兒童都依次售票。售票員需要按照一定的規(guī)則,一定順序把參觀人員一個不落的售完票,其實這個過程就是遍歷,對應的就是計算機設計模式中的迭代器模式。迭代器模式,提供一種方法順序訪問一個聚合對象中的各種元素,而又不暴露該對象的內(nèi)部表示。

  為什么要有迭代器

  回憶在我們的javascript中,可遍歷的結構以及方式有很多。JavaScript 原有的表示“集合”的數(shù)據(jù)結構,主要是數(shù)組(Array)和對象(Object),ES6 又添加了Map和Set,這樣就有了四種數(shù)據(jù)集合,而遍歷這四種結構都有不同的方法。舉個栗子,服務端提供數(shù)據(jù)給前端,前端進行數(shù)據(jù)可視化工作,對數(shù)據(jù)進行遍歷展示使用的for,但是由于業(yè)務的變化,使得后端返回的數(shù)據(jù)結構發(fā)生變化,返回對象或者是set,map,導致前端遍歷代碼大量重寫。而迭代器的目的就是要標準化迭代操作。

  如何部署迭代器接口

  ES6為迭代器引入了一個隱式的標準化接口。Javascript許多內(nèi)建的數(shù)據(jù)結構,例如Array、Map、Set、String、TypedArray、函數(shù)的 arguments 對象、NodeList 對象都具備 Iterator 接口??梢酝ㄟ^在控制臺打印一個Array實例,查看其原型上具有一個Symbol.iterator屬性(Symbol.iterator其實是Symbol('Symbol.iterator')的簡寫,屬性名是Symbol類型代表著這個屬性的唯一以及不可重寫覆蓋),它就是迭代器函數(shù),執(zhí)行這個函數(shù),就會返回一個迭代器對象。

  雖然Javascript許多內(nèi)建的數(shù)據(jù)結構已經(jīng)實現(xiàn)了該接口,還有些結構是沒有迭代器接口的(比如對象),那怎么辦,我們需要寫迭代器,那么就需要知道迭代器是如何工作的。下面代碼實現(xiàn)的一個簡單迭代器:

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  //迭代器就是一個函數(shù),也叫迭代器生成函數(shù)

  function Iterator(o){

  let curIndex = 0;

  let next = () => {

  return {

  value: o[curIndex],

  done: o.length == ++curIndex

  }

  }

  //返回迭代對象,該對象有next方法

  return {

  next

  }

  }

  let arr = [1,2]

  let oIt = Iterator(arr)

  oIt.next();//{value:1,done:false}

  oIt.next();//{value:2,done:false}

  oIt.next();// {value: undefined, done: true}

  oIt.next();// {value: undefined, done: true}

  調用迭代器函數(shù),返回一個對象,該對象就是迭代器對象,對象上擁有next方法,每一次調用next方法,都會返回數(shù)據(jù)結構的當前成員的信息。具體來說,就是返回一個包含value和done兩個屬性的對象。其中,value屬性是當前成員的值,done屬性是一個布爾值,表示遍歷是否結束。
next()迭代

  在上面調用next方法的栗子中,需要注意的是:

  在獲得數(shù)組最后一位元素的時候,迭代器不會報告done:true,這時候需要再次調用next(),越過數(shù)組結尾的值,才能得到完成信號done:true。

  通常情況下,在已經(jīng)迭代完畢的迭代器對象上繼續(xù)調用next方法會繼續(xù)返回{value: undefined, done: true}而不會報錯。

  可選的return()和throw()

  遍歷器對象除了必須具有next方法,還可以具有可選的return方法和throw方法。

  return方法被定義為向迭代器發(fā)送一個信號,表明不會在消費者中再提取出任何值。

  1

  2

  3

  4

  5

  6

  7

  8

  9

  10

  11

  12

  13

  14

  15

  16

  17

  18

  19

  20

  21

  22

  23

  24

  25

  26

  27

  28

  29

  30

  31

  32

  33

  34

  35

  36

  37

  38

  39

  40

  Object.prototype[Symbol.iterator] = function () {

  let curIndex = 0;

  let next = () => {

  return {

  value: this[curIndex],

  done: this.length == curIndex++

  }

  }

  return {

  next,

  return() {

  console.log('執(zhí)行return啦')

  return {}

  }

  }

  }

  let obj = {

  0: 'a',

  1: 'b',

  2: 'c'

  }

  //自動調用---遇到對迭代器消耗提前終止的條件

  for (let item of obj) {

  if (item == 'c') {

  break

  else {

  console.log(item)

  }

  }

  //自動調用---拋出異常

  for (let item of obj) {

  if (item == 'c') {

  throw new Error('Errow')

  else {

  console.log(item)

  }

  }

  //手動調用

  let ot = obj[Symbol.iterator]()

  console.log(ot.return())

  上面代碼中,throw方法的執(zhí)行可以在某種情況下自動被調用,也可以手動調用。throw方法主要向迭代器報告一個異常/錯誤,一般配合生成器使用。

  迭代器分類

  迭代器分為內(nèi)部迭代器和外部迭代器。

·   內(nèi)部迭代器:本身是函數(shù),該函數(shù)內(nèi)部定義好迭代規(guī)則,完全接受整個迭代過程,外部只需要一次調用。例如Array.prototype.forEach方法、jQuery.each都是內(nèi)部迭代器。

·   外部迭代器:本身是函數(shù),執(zhí)行返回迭代對象,迭代下一個元素必須顯式調用。使用forEach遍歷,只可以一次性把數(shù)據(jù)全部拉取消耗,而迭代器可以用于以一次一步的方式控制行為,使得迭代過程更加靈活可控。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多