亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

用ES6重寫(xiě)《JavaScript Patterns》中的設(shè)計(jì)模式

taohonghui / 1809人閱讀

摘要:所以自己動(dòng)手用重新實(shí)現(xiàn)了一遍里面的設(shè)計(jì)模式,算是對(duì)其的鞏固,也算是與大家一起來(lái)研究探討語(yǔ)法的一些最佳實(shí)踐。

前言

最近在回顧設(shè)計(jì)模式方式的知識(shí),重新翻閱了《JavaScript模式》(個(gè)人感覺(jué)也算是一本小有名氣的書(shū)了哈)一書(shū),讀時(shí)總有感觸:在即將到來(lái)的ES6的大潮下,書(shū)中的許多模式的代碼可用ES6的語(yǔ)法更為優(yōu)雅簡(jiǎn)潔的實(shí)現(xiàn),而另一些模式,則已經(jīng)被ES6原生支持,如模塊模式(99頁(yè))。所以自己動(dòng)手用ES6重新實(shí)現(xiàn)了一遍里面的設(shè)計(jì)模式,算是對(duì)其的鞏固,也算是與大家一起來(lái)研究探討ES6語(yǔ)法的一些最佳實(shí)踐。

目錄

(以下所有例子的原型均為《JavaScript模式》一書(shū)里“設(shè)計(jì)模式”章節(jié)中的示例)

單例模式

迭代器模式

工廠模式

裝飾者模式

策略模式

外觀模式

代理模式

訂閱/發(fā)布模式

代碼repo地址,歡迎star,歡迎follow。

實(shí)現(xiàn) 單例模式

主要改變?yōu)槭褂昧薱lass的寫(xiě)法,使對(duì)象原型的寫(xiě)法更為清晰,更整潔:

js"use strict";
let __instance = (function () {
  let instance;
  return (newInstance) => {
    if (newInstance) instance = newInstance;
    return instance;
  }
}());

class Universe {
  constructor() {
    if (__instance()) return __instance();
    //按自己需求實(shí)例化
    this.foo = "bar";
    __instance(this);
  }
}

let u1 = new Universe();
let u2 = new Universe();

console.log(u1.foo); //"bar"
console.log(u1 === u2); //true
迭代器模式

ES6原生提供的Iterator接口就是為這而生的啊,使用胖箭頭函數(shù)寫(xiě)匿名函數(shù)(還順帶綁定了上下文,舒舒服服):

js"use strict";
let agg = {
  data: [1, 2, 3, 4, 5],
  [Symbol.iterator](){
    let index = 0;
    return {
      next: () => {
        if (index < this.data.length) return {value: this.data[index++], done: false};
        return {value: undefined, done: true};
      },
      hasNext: () => index < this.data.length,
      rewind: () => index = 0,
      current: () => {
        index -= 1;
        if (index < this.data.length) return {value: this.data[index++], done: false};
        return {value: undefined, done: true};
      }
    }
  }
};

let iter = agg[Symbol.iterator]();
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
console.log(iter.current());// { value: 2, done: false }
console.log(iter.hasNext());// true
console.log(iter.rewind()); // rewind!
console.log(iter.next()); // { value: 1, done: false }

// for...of
for (let ele of agg) {
  console.log(ele);
}
工廠模式

個(gè)人感覺(jué)變化比較不大的一個(gè):

js"use strict";
class CarMaker {
  constructor() {
    this.doors = 0;
  }

  drive() {
    console.log(`jaja, i have ${this.doors} doors`);
  }

  static factory(type) {
    return new CarMaker[type]();
  }
}

CarMaker.Compact = class Compact extends CarMaker {
  constructor() {
    super();
    this.doors = 4;
  }
};

CarMaker.factory("Compact").drive(); // "jaja, i have 4 doors"
裝飾者模式

for...of循環(huán),新時(shí)代的for (var i = 0 ; i < arr.length ; i++)? :

js"use strict";
class Sale {
  constructor(price) {
    [this.decoratorsList, this.price] = [[], price];
  }

  decorate(decorator) {
    if (!Sale[decorator]) throw new Error(`decorator not exist: ${decorator}`);
    this.decoratorsList.push(Sale[decorator]);
  }

  getPrice() {
    for (let decorator of this.decoratorsList) {
      this.price = decorator(this.price);
    }
    return this.price.toFixed(2);
  }

  static quebec(price) {
    return price + price * 7.5 / 100;
  }

  static fedtax(price) {
    return price + price * 5 / 100;
  }
}

let sale = new Sale(100);
sale.decorate("fedtax");
sale.decorate("quebec");
console.log(sale.getPrice()); //112.88
策略模式

對(duì)于傳統(tǒng)的鍵值對(duì),使用Map來(lái)代替對(duì)象(數(shù)組)來(lái)組織,感覺(jué)帶來(lái)得是更好的語(yǔ)義和更方便的遍歷:

js"use strict";
let data = new Map([["first_name", "Super"], ["last_name", "Man"], ["age", "unknown"], ["username", "o_O"]]);
let config = new Map([["first_name", "isNonEmpty"], ["age", "isNumber"], ["username", "isAlphaNum"]]);

class Checker {
  constructor(check, instructions) {
    [this.check, this.instructions] = [check, instructions];
  }
}

class Validator {
  constructor(config) {
    [this.config, this.messages] = [config, []];
  }

  validate(data) {
    for (let [k, v] of data.entries()) {
      let type = this.config.get(k);
      let checker = Validator[type];
      if (!type) continue;
      if (!checker) throw new Error(`No handler to validate type ${type}`);
      let result = checker.check(v);
      if (!result) this.messages.push(checker.instructions + ` **${v}**`);
    }
  }

  hasError() {
    return this.messages.length !== 0;
  }
}

Validator.isNumber = new Checker((val) => !isNaN(val), "the value can only be a valid number");
Validator.isNonEmpty = new Checker((val) => val !== "", "the value can not be empty");
Validator.isAlphaNum = new Checker((val) => !/^a-z0-9/i.test(val), "the value can not have special symbols");

let validator = new Validator(config);
validator.validate(data);
console.log(validator.messages.join("
")); //the value can only be a valid number **unknown**
外觀模式

這個(gè)簡(jiǎn)直沒(méi)啥好變的。。。:

js"use strict";
let nextTick = (global.setImmediate == undefined) ? process.nextTick : global.setImmediate;
代理模式

利用extends關(guān)鍵字來(lái)獲得父類(lèi)中的方法引用以及和父類(lèi)相同的類(lèi)接口:

js"use strict";
class Real {
  doSomething() {
    console.log("do something...");
  }
}

class Proxy extends Real {
  constructor() {
    super();
  }

  doSomething() {
    setTimeout(super.doSomething, 1000 * 3);
  }
}

new Proxy().doSomething(); //after 3s ,do something...
訂閱/發(fā)布模式

被Node原生的Events模塊所支持,同樣結(jié)合默認(rèn)參數(shù),for...of遍歷等特性,代碼的減少以及可讀性的增加都是可觀的:

js"use strict";
class Event {
  constructor() {
    this.subscribers = new Map([["any", []]]);
  }

  on(fn, type = "any") {
    let subs = this.subscribers;
    if (!subs.get(type)) return subs.set(type, [fn]);
    subs.set(type, (subs.get(type).push(fn)));
  }

  emit(content, type = "any") {
    for (let fn of this.subscribers.get(type)) {
      fn(content);
    }
  }
}

let event = new Event();

event.on((content) => console.log(`get published content: ${content}`), "myEvent");
event.emit("jaja", "myEvent"); //get published content: jaja
最后

以上所有代碼均可通過(guò)Babel跑通,90%以上的代碼可被當(dāng)前版本的io.js(v2.0.2)跑通。

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

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

相關(guān)文章

  • FE.BASE-前端設(shè)計(jì)模式、編碼與重構(gòu)筆記

    摘要:高質(zhì)量特性面向?qū)ο?,無(wú)類(lèi),原型可維護(hù)的代碼可讀一致可預(yù)測(cè)看起來(lái)像是同一個(gè)人寫(xiě)的文檔減少全局對(duì)象,傳參訪問(wèn)全局對(duì)象單模式,忘記時(shí)的副作用顯式聲明的全局變量無(wú)法用刪除不擴(kuò)充內(nèi)置原型模式每個(gè)和對(duì)齊這里不考慮花括號(hào)相關(guān)的縮進(jìn)規(guī)則每個(gè)中的代碼整齊縮進(jìn) 高質(zhì)量Javascript Javascript特性:面向?qū)ο?,無(wú)類(lèi),原型 可維護(hù)的代碼(可讀;一致;可預(yù)測(cè);看起來(lái)像是同一個(gè)人寫(xiě)的;文檔) 減...

    SmallBoyO 評(píng)論0 收藏0
  • JavaScript設(shè)計(jì)模式

    摘要:此處的構(gòu)造函數(shù)使用的形式添加新屬性,但實(shí)際上新屬性的添加有四種方式,除去這一種,還有三種方括號(hào)語(yǔ)法,方法方法此處舉的是原文中的例子,若要使用,可參考原文。 參考書(shū)籍Learning Javascript Design Patterns 一、設(shè)計(jì)模式概述與應(yīng)用場(chǎng)景 首先引用原書(shū)的一段話: Patterns are proven solutions: They provide solid ...

    dreambei 評(píng)論0 收藏0
  • 深入理解 ES6 的解構(gòu)賦值

    摘要:在可遍歷的量中使用數(shù)組模型數(shù)組解構(gòu)使用一個(gè)迭代器來(lái)獲取數(shù)據(jù)源中的元素。所以,數(shù)組解構(gòu)能夠在上工作的迭代器總是按照元素插入的順序?qū)⒃胤祷?,所以上述的解?gòu)返回的結(jié)果總是相同的。 解構(gòu)賦值(destructuring assignment)語(yǔ)法是一個(gè)Javascript表達(dá)式,這種語(yǔ)法能夠更方便的提取出 Object 或者 Array 中的數(shù)據(jù)。這種語(yǔ)法可以在接受提取的數(shù)據(jù)的地方使用,比如...

    only_do 評(píng)論0 收藏0
  • 設(shè)計(jì)模式: 從ES5 到 TypeScript ——單例模式

    摘要:現(xiàn)在讓我們?cè)O(shè)置溫度值并將其增加減少幾次小結(jié)在中,單例模式根據(jù)是否懶漢模式餓漢模式以及是否線程安全,分為很多種實(shí)現(xiàn)方式。參考設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐設(shè)計(jì)模式 Back in 1994, a book was authored by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides that discusses 23 desg...

    王軍 評(píng)論0 收藏0
  • ES6 Promise:模式與反模式

    摘要:盡管可以讓代碼更加簡(jiǎn)潔易讀,但對(duì)于只熟悉回調(diào)函數(shù)的人來(lái)說(shuō),可能對(duì)此還是會(huì)有所懷疑。始終避免在或使用回調(diào)函數(shù),否則會(huì)吞噬任何后續(xù)的錯(cuò)誤,將其作為鏈的一部分。然而,使用回調(diào)函數(shù),使用所謂的,即第一個(gè)參數(shù)是一個(gè)錯(cuò)誤回調(diào)變得很常見(jiàn)。 原文:ES6 Promises: Patterns and Anti-Patterns作者:Bobby Brennan 當(dāng)幾年前,第一次使用 NodeJS 的時(shí)候...

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

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

0條評(píng)論

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