欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Javascript設(shè)計(jì)模式之原型模式詳細(xì)

 更新時(shí)間:2021年09月29日 17:02:06   作者:leayun  
這篇文章主要介紹了Javascript設(shè)計(jì)模式之原型模式,原型模式用于在創(chuàng)建對(duì)象時(shí),通過共享某個(gè)對(duì)象原型的屬性和方法,從而達(dá)到提高性能、降低內(nèi)存占用、代碼復(fù)用的效果。下面小編將詳細(xì)介紹 ,需要的朋友可以參考下

1、原型模式

原型模式用于在創(chuàng)建對(duì)象時(shí),通過共享某個(gè)對(duì)象原型的屬性和方法,從而達(dá)到提高性能、降低內(nèi)存占用、代碼復(fù)用的效果。

示例一

function Person(name) {
  this.name = name;

  this.config = {
    a: "1",
    b: "2",
  };

  this.hello = function () {
    console.info("hello");
  };
}

假如需要通過以上代碼創(chuàng)建 100 個(gè)實(shí)例,那么將需要?jiǎng)?chuàng)建 100 個(gè) config、100 個(gè) hello,而這兩個(gè)東西在每個(gè)實(shí)例里面是完全一樣的。

因此我們可以通過提取公共代碼的方式進(jìn)行油優(yōu)化。

const config = {
  a: "1",
  b: "2",
};
const hello = function () {
  console.info("hello");
};
function Person(name) {
  this.name = name;

  this.config = config;

  this.hello = hello
}

這樣的方式使得無(wú)論創(chuàng)建多少個(gè)Person對(duì)象都只需要?jiǎng)?chuàng)建一個(gè)config、一個(gè)hello。 但是仍然污染全局變量、config被誤修改、Person和其他代碼耦合大、不易于代碼擴(kuò)展維護(hù)等問題。

因此可以通過原型的方式進(jìn)行優(yōu)化。

function Person() {}
var p = new Person();


該函數(shù)創(chuàng)建實(shí)例時(shí)原型圖如下:

示例二

function Person(name) {
  this.name = name;

  this.config = {
    a: "1",
    b: "2",
  };

  this.hello = function () {
    console.info("hello");
  };
}

//此方式會(huì)重寫prototype,造成constructor丟失,變?yōu)镺bject()。
//可以使用Person.prototype.xx=yy的方式寫,或者重新指定Person.prototype.constructor=Person
Person.prototype = {
  version: 1.0,
  say: function (arg) {
    console.info(`${this.name} say ${arg}`);
  },
  constructor: Person,
};
var p1 = new Person("p1");
var p2 = new Person("p2");

console.info(p1.config == p2.config); //false
console.info(p1.hello == p2.hello); //false
console.info(p1.say === p2.say); //true
p1.say("qq");
p2.say("qq");
console.info(p1.version === p2.version); //true
console.info(p1.version);

該函數(shù)創(chuàng)建實(shí)例時(shí)原型圖如下:

示例三

function Person(name) {
  this.name = name;

  this.config = {
    a: "1",
    b: "2",
  };

  this.hello = function () {
    console.info("hello");
  };
}

//此方式會(huì)重寫prototype,造成constructor丟失,變?yōu)镺bject()
Person.prototype = {
  version: 1.0,
  say: function (arg) {
    console.info(`${this.name} say ${arg}`);
  },
};

function PersonA(name) {
  Person.call(this, name);
}
PersonA.prototype = Person.prototype;

function PersonB(name) {
  Person.call(this, name);
}
PersonB.prototype = Person.prototype;
var pA = new PersonA("pa");
var pB = new PersonB("pb");

console.info(pA.config == pB.config); //false  內(nèi)部屬性比較
console.info(pA.hello == pB.hello); //false  內(nèi)部屬性比較
console.info(pA.say === pB.say); //true  原型方法共享
pA.say("qq");
pB.say("qq");
console.info(pA.version === pB.version); //true  原型屬性共享
console.info(pA.version); //1.0
Person.prototype.version = 2.0; //修改原型共享屬性
console.info(pB.version); //2.0
console.info(new Person().version); //2.0

//修改原型共享方法
PersonB.prototype.say = function (arg) {
  console.info(`v2--- ${this.name} say ${arg}`);
};
pB.say("qq");
new Person("Person").say("ww");

總結(jié):

js 在創(chuàng)建對(duì)象比較消耗內(nèi)存、耗時(shí)長(zhǎng),可以通過減少內(nèi)部屬性創(chuàng)建的方式降低內(nèi)存占用。

而原型模式就是使用 javascript 語(yǔ)言的原型特性進(jìn)行相同屬性的共享,從而達(dá)到降低內(nèi)存占用、提高對(duì)象創(chuàng)建效率。

2、觀察者模式

觀察者模式用于模塊、組件之間通訊,通過提供統(tǒng)一的模式進(jìn)行事件訂閱、事件發(fā)布。從而達(dá)到模塊、組件之間解耦,提高代碼的可維護(hù)性。

模塊之間、組件之間通訊方式

模塊之間、組件之間采用直接引用通訊方式

const moduleA = {
  say: function (msg) {
    console.info("A say " + msg);
  },

  letBrun: function () {
    //直接引用了moduleB
    moduleB.run();
  },
};

const moduleB = {
  run: function () {
    console.info("B run ");
  },

  letAsay: function () {
    //直接引用了moduleA
    moduleA.say("hello");
  },
};

moduleA.letBrun(); //B Run
moduleB.letAsay(); //A say hello

模塊之間、組件之間采用父組件通訊方式

const moduleA = {
  say: function (msg) {
    console.info("A say " + msg);
  },
};

const moduleB = {
  run: function () {
    console.info("B run ");
  },
};

const parentModule = {
  moduleA,
  moduleB,

  letBrun: function () {
    this.moduleB.run();
  },

  letAsay: function () {
    this.moduleA.say("hello");
  },
};

parentModule.letBrun(); //B Run
parentModule.letAsay(); //A say hello

事件模塊實(shí)現(xiàn)通訊

function Emitter() {
  this.events = {};
  this.res_oldAction = {}
  this.res_action_events = {}
}

//訂閱資源
Emitter.prototype.subscribe = function (res, action, fn) {
  if(!this.res_oldAction[res.name]){
 this.res_oldAction[res.name] = res[action]
 res[action] = (data) => {
      this.res_oldAction[res.name](data)
   const fns = this.res_action_events[res.name].action;
      for (let i = 0; i < fns.length; i++) {
        fns[i](data);
      }
    }
  }
  
  if(!this.res_action_events[res.name]){
 this.res_action_events[res.name] = {}
  }
  
  if(!this.res_action_events[res.name][action]){
 this.res_action_events[res.name][action] = []
  }
  
  this.res_action_events[res.name].action.push(fn)
}

//取消訂閱資源
Emitter.prototype.unsubscribe = function (res, action, fn) {
  const fns = this.res_action_events[res.name].action;
  for (let i = 0; i < fns.length; i++) {
 if (fns[i] === fn) {
   fns.splice(i, 1);
   i--;
 }
  }
}

Emitter.prototype.on = function (name, fn) {
  if (!this.events[name]) {
    this.events[name] = [];
  }

  this.events[name].push(fn);
};

Emitter.prototype.remove = function (name, fn) {
  if (!this.events[name]) {
    return;
  }

  const fns = this.events[name];

  for (let i = 0; i < fns.length; i++) {
    if (fns[i] === fn) {
      fns.splice(i, 1);
      i--;
    }
  }
};

Emitter.prototype.fire = function (name, data) {
  if (!this.events[name]) {
    return;
  }

  const fns = this.events[name];

  for (let i = 0; i < fns.length; i++) {
    fns[i](data);
  }
};

const emitter = new Emitter();

//模塊A中注冊(cè)事件
const methodA = (data) => {
  console.info("模塊A接受到food消息:");
  console.info(data);
};

emitter.on("food", methodA);

//模塊B中注冊(cè)事件
const methodB = (data) => {
  console.info("模塊B接受到food消息:");
  console.info(data);
};
emitter.on("food", methodB);

//模塊C中觸發(fā)事件
emitter.fire("food", "飯來(lái)了");

//模塊B中移除事件
emitter.remove("food", methodB);

//模塊C中再次觸發(fā)事件
emitter.fire("food", "飯又來(lái)了");

執(zhí)行結(jié)果如下:

模塊 A 接受到 food 消息:

飯來(lái)了

模塊 B 接受到 food 消息:

飯來(lái)了

模塊 A 接受到 food 消息:

飯又來(lái)了

總結(jié):

js 組件模塊的通訊方式一般分為3種(直接通訊、通過父組件通訊、通過事件模塊通訊)。觀察者模式用于模塊、組件之間通訊,通過提供統(tǒng)一的模式進(jìn)行事件訂閱、事件發(fā)布,從而達(dá)到模塊、組件之間解耦,提高代碼的可維護(hù)性

到此這篇關(guān)于Javascript設(shè)計(jì)模式之原型模式詳細(xì)的文章就介紹到這了,更多相關(guān)Javascript原型模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論