成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從迭代器模式到迭代協(xié)議

doodlewind / 3033人閱讀

摘要:迭代器模式迭代器模式是指提供一種方法順序訪問一個(gè)聚合對象中的各個(gè)元素,而不需要暴露該對象的內(nèi)部表示??傻鷧f(xié)議和迭代器協(xié)議。生成器函數(shù)是可以作為迭代器工廠的函數(shù),當(dāng)它被執(zhí)行時(shí)會返回一個(gè)新的對象,該對象符合可迭代協(xié)議和迭代器協(xié)議。

迭代器模式

迭代器模式是指提供一種方法順序訪問一個(gè)聚合對象中的各個(gè)元素,而不需要暴露該對象的內(nèi)部表示。

迭代器分為內(nèi)部迭代器和外部迭代器。內(nèi)部迭代器只需一次初始調(diào)用,而外部迭代器必須顯式地請求迭代下一個(gè)元素,這樣我們就可以手動控制迭代過程。

實(shí)現(xiàn)一個(gè)內(nèi)部迭代器:

Array.prototype.innerIterator = function(callback){
    for (let i = 0, len = this.length; i < len; i++) {
        callback && callback.call(this[i], this[i], i)
    }
};
[1,2,3].innerIterator(function(item, index){
    console.log("item:", item, "index:", index)
})
// item: 1 index: 0
// item: 2 index: 1
// item: 3 index: 2

實(shí)現(xiàn)一個(gè)外部迭代器:

Array.prototype.outerInterator = function(){
    let index = 0;
        return {
            next: () => {
                return index < this.length ?
                {value: this[index++], done: false}:
                {value: undefined, done: true}
            }
    }
}
let iterator = [1,2,3].outerInterator();

for(let next; (next = iterator.next()) && !next.done;) {
    console.log("item", next.value)
}
// item 1
// item 2
// item 3
迭代協(xié)議

了解了迭代器模式,再來看看 ES6 中補(bǔ)充的迭代協(xié)議。可迭代(iterable)協(xié)議和迭代器(iterator)協(xié)議。

可迭代協(xié)議:
一個(gè)可迭代對象(或其原型上),必須有一個(gè) Symbol.iterator 的屬性,該屬性所對應(yīng)的值為返回一個(gè)對象的無參函數(shù),被返回對象符合迭代器協(xié)議。當(dāng)可迭代對象需要迭代時(shí),調(diào)用該方法。

一些數(shù)據(jù)類型內(nèi)置了 @@iterator 方法,有自己默認(rèn)的迭代行為。(String, Array, TypedArray, Map , Set 等都是內(nèi)置可迭代對象, 因?yàn)樗鼈兊脑蛯ο蠖加幸粋€(gè) @@iterator 方法.)([Symbol.iterator]@@iterator 可以認(rèn)為是一回事

let iterator = ("hi")[Symbol.iterator]()
var a = iterator.next();
// a { value: "h", done: false }

迭代器協(xié)議:
一個(gè)迭代器必須實(shí)現(xiàn)了 next() 方法,該方法是返回一個(gè)對象的無參函數(shù)。被返回的對象有兩個(gè)必要的屬性:done 和 value。

Array.prototype.Iteration = function(){
    let index = 0;
        return {
            [Symbol.iterator](){return this},
            next: () => {
                return index < this.length ?
                {value: this[index++], done: false}:
                {value: undefined, done: true}
            }
    }
};
let Iteration = [2, 3, 4].Iteration();
for(let value of Iteration) {
    console.log("value", value)
}
// value 2
// value 3
// value 4

不能發(fā)現(xiàn),Iteration 同時(shí)滿足可迭代協(xié)議和迭代協(xié)議。又因?yàn)槭强傻模?b>for...of 是可以直接使用,而且這個(gè)和外部迭代器十分相似。

一旦一種數(shù)據(jù)結(jié)構(gòu)有了 @@iterator 方法后, 就認(rèn)為是可迭代的。ES6 中許多新的方法就是基于此的 解構(gòu)賦值、擴(kuò)展運(yùn)算符、yield*,還有 for..of、Array.from()等。

知道了以上知識,也就知道了為什么對象不可以直接使用 for...of 了。不過我們可以在對象原型上添加 @@iterator 方法,使之成為可迭代的。

Object.prototype.Iteration = function(){
    let keys = Object.keys(this), index = 0;
        return{
            [Symbol.iterator](){return this},
            next: () => {
                let current = index++;
                return current < keys.length?
                {value: [keys[current], this[keys[current]]], done: false}:
                {value: undefined, done: true};
            }
        }
}
let iterator = {"a": 1, "b": 2, "c": 3}.Iteration();
    for(let [key, value] of iterator) {
        console.log("key:", key, "value:", value)
}
// key: a value: 1
// key: b value: 2
// key: c value: 3
生成器

像以上的的對象都是我們自己手動實(shí)現(xiàn)的,符合可迭代協(xié)議和迭代協(xié)議的對象。看起來很麻煩,還好這些工作已經(jīng)有函數(shù)替我們做了,那就是生成器函數(shù)。

生成器函數(shù)是可以作為迭代器工廠的函數(shù),當(dāng)它被執(zhí)行時(shí)會返回一個(gè)新的 Generator 對象,該對象符合可迭代協(xié)議和迭代器協(xié)議。

現(xiàn)在我們用生成器函數(shù)使得對象符合迭代協(xié)議:

Object.prototype.Iteration = function *(){
    for(let [key, value] of Object.entries(this)){
        yield [key, value]
    }
}
for(let [key, value] of {"a": 1, "b": 2, "c": 3}.Iteration()) {
    console.log("key:", key, "value:", value)
}
// key: a value: 1
// key: b value: 2
// key: c value: 3

在這里生成器只是作為迭代器而已,其實(shí)它還是消息雙向傳遞系統(tǒng)。也正是這些特性的存在,使得異步流程控制又向前邁了一大步。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/102756.html

相關(guān)文章

  • Python標(biāo)準(zhǔn)庫---11、內(nèi)置類型:迭代類型、序列類型(list-typle-range)

    摘要:上一篇文章標(biāo)準(zhǔn)庫內(nèi)置類型數(shù)字類型下一篇文章標(biāo)準(zhǔn)庫內(nèi)置類型文本序列類型迭代器類型支持在容器中進(jìn)行迭代的概念。該對象需要支持下文所述的迭代器協(xié)議。這是同時(shí)允許容器和迭代器配合和語句使用所必須的。 上一篇文章:Python標(biāo)準(zhǔn)庫---10、內(nèi)置類型:數(shù)字類型下一篇文章:Python標(biāo)準(zhǔn)庫---12、內(nèi)置類型:文本序列類型(str) ## 迭代器類型Python 支持在容器中進(jìn)行迭代的概念。...

    syoya 評論0 收藏0
  • 當(dāng)談?wù)?em>迭代時(shí),我談些什么?

    摘要:示例代碼如下此示例中可以看出,當(dāng)?shù)鹘K止時(shí),通過拋出異常告知迭代器已耗盡。但如果迭代器所指向的數(shù)據(jù)結(jié)構(gòu)在其存在時(shí)發(fā)生了插入或刪除操作,則迭代器將可能失效。與的情形類似,對進(jìn)行任何插入操作也將損壞迭代器。 花下貓語:之前說過,我對于編程語言跟其它學(xué)科的融合非常感興趣,但我還說漏了一點(diǎn),就是我對于 Python 跟其它編程語言的對比學(xué)習(xí),也很感興趣。所以,我一直希望能聚集一些有其它語言基...

    王軍 評論0 收藏0
  • Python中的可迭代的對象、迭代和生成

    摘要:本文重點(diǎn)掌握可迭代的對象的定義掌握可迭代對象迭代器與生成器之間的關(guān)系和異同熟悉標(biāo)準(zhǔn)庫中生成器。二迭代器迭代器介紹迭代器用于從集合中取出元素的對象。若想再次迭代須重建迭代器。迭代器檢查方式調(diào)用,。區(qū)別可迭代的對象不是迭代器。 導(dǎo)語:本文章記錄了本人在學(xué)習(xí)Python基礎(chǔ)之控制流程篇的重點(diǎn)知識及個(gè)人心得,打算入門Python的朋友們可以來一起學(xué)習(xí)并交流。 本文重點(diǎn): 1、掌握可迭代的對象的...

    starsfun 評論0 收藏0
  • forEach迭代

    摘要:本文從使用對數(shù)組進(jìn)行遍歷開始說起,粗略對比使用進(jìn)行遍歷的差異,并由此引入中可迭代對象迭代器的概念,并對其進(jìn)行粗略介紹。說到這里,就繼續(xù)說一下迭代器關(guān)閉的情況了。確實(shí),符合可迭代協(xié)議和迭代器協(xié)議的。 本文從使用 forEach 對數(shù)組進(jìn)行遍歷開始說起,粗略對比使用 forEach , for...in , for...of 進(jìn)行遍歷的差異,并由此引入 ES6 中 可迭代對象/迭代器 的概...

    rockswang 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<