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

資訊專欄INFORMATION COLUMN

js設(shè)計(jì)模式--迭代器模式

binta / 1202人閱讀

摘要:文章系列設(shè)計(jì)模式單例模式設(shè)計(jì)模式策略模式設(shè)計(jì)模式代理模式概念迭代器模式是指提供一種方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。

前言

本系列文章主要根據(jù)《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》整理而來,其中會(huì)加入了一些自己的思考。希望對(duì)大家有所幫助。

文章系列

js設(shè)計(jì)模式--單例模式

js設(shè)計(jì)模式--策略模式

js設(shè)計(jì)模式--代理模式

概念

迭代器模式是指提供一種方法順序訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。迭代器模式可以把迭代的過程從業(yè)務(wù)邏輯中分離出來,在使用迭代器模式之后,即使不關(guān)心對(duì)象的內(nèi)部構(gòu)造,也可以按順序訪問其中的每個(gè)元素。

UML類圖

場(chǎng)景

JavaScript已經(jīng)內(nèi)置迭代器,如forEach Iterator等,再如jquery的$.each

分類 內(nèi)部迭代器 定義
內(nèi)部已經(jīng)定義好了迭代規(guī)則,它完全接手整個(gè)迭代過程,外部只需要一次初始調(diào)用
實(shí)現(xiàn)
var each = function (ary, callback) {
  for (var i = 0; i < ary.length; i++) {
    callback(i, ary[i])
  }
}
each([1, 2, 3, 4, 5], function (i, item) {
  console.log(i, item)
})
優(yōu)缺點(diǎn)

優(yōu)點(diǎn):內(nèi)部迭代器在調(diào)用的時(shí)候非常方便,外界不用關(guān)心迭代器內(nèi)部的實(shí)現(xiàn),跟迭代器的交互也僅 僅是一次初始調(diào)用

缺點(diǎn):由于內(nèi)部迭代器的迭代規(guī)則已經(jīng)被提前規(guī) 定,上面的 each 函數(shù)就無法同時(shí)迭代2個(gè)數(shù)組,如下代碼

var compare = function( ary1, ary2 ){
  if ( ary1.length !== ary2.length ){
    throw new Error ( "ary1 和ary2 不相等" );
  }
  each( ary1, function( i, n ){
    if ( n !== ary2[ i ] ){
      throw new Error ( "ary1 和ary2 不相等" );
    }
  });
  alert ( "ary1 和ary2 相等" );
};
compare( [ 1, 2, 3 ], [ 1, 2, 4 ] ); // throw new Error ( "ary1 和ary2 不相等" );
外部迭代器 定義
外部迭代器必須顯式地請(qǐng)求迭代下一個(gè)元素
實(shí)現(xiàn)

我們模擬一個(gè)es6迭代器

var Iterator = function (ary) {
  this.ary = ary
  this.index = 0
}

Iterator.prototype.isDone = function () {
  return this.index >= this.ary.length
}

Iterator.prototype.next = function () {
  if (!this.isDone()) {
    var res = this.ary[this.index]
    this.index++
    return {
      value: res,
      done: this.isDone()
    }
  }
}

var a = new Iterator([1, 2, 3])

while (!a.isDone()) {
  console.log(a.next())
}

下面解決一下上面那個(gè)問題

var a = new Iterator([1, 2, 3, 3])
var b = new Iterator([1, 2, 3])

function compare(iterator1, iterator2) {
  while (!iterator1.isDone() || !iterator2.isDone()) {
    if (iterator1.next().value !== iterator2.next().value) {
      return false
    }
  }
  return true
}


compare(a, b)
例子 文件上傳 實(shí)現(xiàn)文件上傳對(duì)象
var getUploadObj = function () {
  try {
    return new ActiveXObject("TXFTNActiveX.FTNUpload");
  } catch (e) {
    // IE 上傳控件
    if (supportFlash()) { // supportFlash 函數(shù)未提供
      var str = "";
      return $(str).appendTo($("body"));
    } else {
      var str = ""; // 表單上傳
      return $(str).appendTo($("body"));
    }
  }
};

缺點(diǎn):第一是很難閱讀,第二是嚴(yán)重違反開閉原則

改進(jìn)
var getActiveUploadObj = function () {
  try {
    return new ActiveXObject("TXFTNActiveX.FTNUpload");
  } catch (e) {
    return false;
  }
};

var getFlashUploadObj = function () {
  if (supportFlash()) { // supportFlash 函數(shù)未提供
    var str = "";
    return $(str).appendTo($("body"));
  };
  return false;
}

var getFormUpladObj = function () {
  var str = " "; // 表單上傳
  return $(str).appendTo($("body"));
}

var iteratorUploadObj = function () {
  for (var i = 0, fn; fn = arguments[i++];) {
    var uploadObj = fn();
    if (uploadObj !== false) {
      return uploadObj;
    }
  };
}
var uploadObj = iteratorUploadObj(getActiveUploadObj, getFlashUploadObj, getFormUpladObj);
es6 基于類實(shí)現(xiàn)
class Iterator {
    constructor(conatiner) {
        this.list = conatiner.list
        this.index = 0
    }
    next() {
        if (this.hasNext()) {
            return this.list[this.index++]
        }
        return null
    }
    hasNext() {
        if (this.index >= this.list.length) {
            return false
        }
        return true
    }
}

class Container {
    constructor(list) {
        this.list = list
    }
    getIterator() {
        return new Iterator(this)
    }
}

// 測(cè)試代碼
let container = new Container([1, 2, 3, 4, 5])
let iterator = container.getIterator()
while(iterator.hasNext()) {
    console.log(iterator.next())
}
es6中的Iterator

我們都知道Array、Map、Set、類對(duì)象(如arguments NodeList等)都有一個(gè)Symbol.iterator迭代方法,可以通過以下方式取得

var a = [1,2,3]
console.log(a[Symbol.iterator])

另外generator也會(huì)返回迭代器

function* gen() {
  yield 1
  yield "1"
}

var a = gen()
a.next()

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

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

相關(guān)文章

  • JS迭代模式《JavaScript設(shè)計(jì)模式與開發(fā)實(shí)踐》閱讀筆記

    摘要:但實(shí)際中,內(nèi)部迭代器和外部迭代器兩者并無優(yōu)劣。迭代器并不只迭代數(shù)組迭代器模式不僅能迭代數(shù)組,還可以迭代一些類數(shù)組對(duì)象。晚安了,參考設(shè)計(jì)模式與開發(fā)實(shí)踐曾探本文作者本文鏈接迭代器模式設(shè)計(jì)模式與開發(fā)實(shí)踐閱讀筆記 迭代器模式:一個(gè)相對(duì)簡(jiǎn)單的模式,目前絕大多數(shù)語言都內(nèi)置了迭代器,以至于大家都不覺得這是一種設(shè)計(jì)模式 迭代器模式 迭代器模式指提供一種方法訪問一個(gè)聚合對(duì)象中的各個(gè)元素,而又不需要暴露該...

    djfml 評(píng)論0 收藏0
  • 從觀察者模式迭代模式系統(tǒng)講解 RxJS Observable(一)

    摘要:是的縮寫,起源于,是一個(gè)基于可觀測(cè)數(shù)據(jù)流結(jié)合觀察者模式和迭代器模式的一種異步編程的應(yīng)用庫。是基于觀察者模式和迭代器模式以函數(shù)式編程思維來實(shí)現(xiàn)的。學(xué)習(xí)之前我們需要先了解觀察者模式和迭代器模式,還要對(duì)流的概念有所認(rèn)識(shí)。 RxJS 是 Reactive Extensions for JavaScript 的縮寫,起源于 Reactive Extensions,是一個(gè)基于可觀測(cè)數(shù)據(jù)流 Stre...

    notebin 評(píng)論0 收藏0
  • ES6 Features系列:GeneratorFunction介紹

    摘要:沒有顯示顯示顯示關(guān)鍵字迭代器生成器用于馬上退出代碼塊并保留現(xiàn)場(chǎng),當(dāng)執(zhí)行迭代器的函數(shù)時(shí),則能從退出點(diǎn)恢復(fù)現(xiàn)場(chǎng)并繼續(xù)執(zhí)行下去。迭代器迭代器是一個(gè)擁有方法和方法的對(duì)象,通過函數(shù)不斷執(zhí)行以關(guān)鍵字分割的代碼段,通過函數(shù)令分割的代碼段拋出異常。 一、前言                            第一次看koajs的示例時(shí),發(fā)現(xiàn)該語句 function *(next){..........

    golden_hamster 評(píng)論0 收藏0
  • javascript中的設(shè)計(jì)模式(一)

    摘要:模式迭代器模式顧名思義,迭代器可以將對(duì)于一個(gè)聚合對(duì)象內(nèi)部元素的訪問與業(yè)務(wù)邏輯分離開。模式組合模式組合模式將對(duì)象組合成樹形結(jié)構(gòu),以表示層級(jí)結(jié)構(gòu)。重點(diǎn)是,葉結(jié)點(diǎn)與中間結(jié)點(diǎn)有統(tǒng)一借口。本文總結(jié)自設(shè)計(jì)模式與開發(fā)實(shí)踐,曾探著 模式1 - 單例模式 單例模式的核心是確保只有一個(gè)實(shí)例,并且提供全局訪問。 特點(diǎn): 滿足單一職責(zé)原則 : 使用代理模式,不在構(gòu)造函數(shù)中判斷是否已經(jīng)創(chuàng)建過該單例; 滿足惰...

    chaosx110 評(píng)論0 收藏0
  • [譯] ES6 學(xué)習(xí)筆記:關(guān)于 ES2015 特性的詳細(xì)概述

    摘要:將轉(zhuǎn)換成常見的使用實(shí)現(xiàn)的基于迭代器的迭代。處停止迭代器基于鴨子模型接口這里使用語法僅僅為了說明問題使用支持為了使用迭代器屬性需要引入。生成器是迭代器的子類,包含了附加的與。 原文地址:http://babeljs.io/docs/learn-...本文基于Luke Hoban精妙的文章《es6features》,請(qǐng)把star獻(xiàn)給他,你可以在此嘗試這些特性REPL。 概述 ECMAScr...

    leoperfect 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<