乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      JavaScript迭代器的含義

       好程序員IT 2019-07-19

      什么是迭代器

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

        迭代器模式

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

        為什么要有迭代器

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

        如何部署迭代器接口

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

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

        1

        2

        3

        4

        5

        6

        7

        8

        9

        10

        11

        12

        13

        14

        15

        16

        17

        18

        19

        20

        //迭代器就是一個(gè)函數(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}

        調(diào)用迭代器函數(shù),返回一個(gè)對象,該對象就是迭代器對象,對象上擁有next方法,每一次調(diào)用next方法,都會(huì)返回?cái)?shù)據(jù)結(jié)構(gòu)的當(dāng)前成員的信息。具體來說,就是返回一個(gè)包含value和done兩個(gè)屬性的對象。其中,value屬性是當(dāng)前成員的值,done屬性是一個(gè)布爾值,表示遍歷是否結(jié)束。
      next()迭代

        在上面調(diào)用next方法的栗子中,需要注意的是:

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

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

        可選的return()和throw()

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

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

        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'

        }

        //自動(dòng)調(diào)用---遇到對迭代器消耗提前終止的條件

        for (let item of obj) {

        if (item == 'c') {

        break

        else {

        console.log(item)

        }

        }

        //自動(dòng)調(diào)用---拋出異常

        for (let item of obj) {

        if (item == 'c') {

        throw new Error('Errow')

        else {

        console.log(item)

        }

        }

        //手動(dòng)調(diào)用

        let ot = obj[Symbol.iterator]()

        console.log(ot.return())

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

        迭代器分類

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

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

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

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

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多