千家信息网

Javascript中原型模式是怎样的

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇文章给大家介绍Javascript中原型模式是怎样的 ,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、原型模式原型模式用于在创建对象时,通过共享某个对象原型的属性和方法,从
千家信息网最后更新 2025年02月01日Javascript中原型模式是怎样的

这篇文章给大家介绍Javascript中原型模式是怎样的 ,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

1、原型模式

原型模式用于在创建对象时,通过共享某个对象原型的属性和方法,从而达到提高性能、降低内存占用、代码复用的效果。

示例一

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

假如需要通过以上代码创建 100 个实例,那么将需要创建 100 个 config、100 个 hello,而这两个东西在每个实例里面是完全一样的。

因此我们可以通过提取公共代码的方式进行油优化。

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

这样的方式使得无论创建多少个Person对象都只需要创建一个config、一个hello。 但是仍然污染全局变量、config被误修改、Person和其他代码耦合大、不易于代码扩展维护等问题。

因此可以通过原型的方式进行优化。

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

该函数创建实例时原型图如下:

示例二

function Person(name) {  this.name = name;  this.config = {    a: "1",    b: "2",  };  this.hello = function () {    console.info("hello");  };}//此方式会重写prototype,造成constructor丢失,变为Object()。//可以使用Person.prototype.xx=yy的方式写,或者重新指定Person.prototype.constructor=PersonPerson.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); //falseconsole.info(p1.hello == p2.hello); //falseconsole.info(p1.say === p2.say); //truep1.say("qq");p2.say("qq");console.info(p1.version === p2.version); //trueconsole.info(p1.version);

该函数创建实例时原型图如下:

示例三

function Person(name) {  this.name = name;  this.config = {    a: "1",    b: "2",  };  this.hello = function () {    console.info("hello");  };}//此方式会重写prototype,造成constructor丢失,变为Object()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  内部属性比较console.info(pA.hello == pB.hello); //false  内部属性比较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.0Person.prototype.version = 2.0; //修改原型共享属性console.info(pB.version); //2.0console.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");

总结:

js 在创建对象比较消耗内存、耗时长,可以通过减少内部属性创建的方式降低内存占用。

而原型模式就是使用 javascript 语言的原型特性进行相同属性的共享,从而达到降低内存占用、提高对象创建效率。

2、观察者模式

观察者模式用于模块、组件之间通讯,通过提供统一的模式进行事件订阅、事件发布。从而达到模块、组件之间解耦,提高代码的可维护性。

模块之间、组件之间通讯方式

模块之间、组件之间采用直接引用通讯方式

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 RunmoduleB.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 RunparentModule.letAsay(); //A say hello

事件模块实现通讯

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中注册事件const methodA = (data) => {  console.info("模块A接受到food消息:");  console.info(data);};emitter.on("food", methodA);//模块B中注册事件const methodB = (data) => {  console.info("模块B接受到food消息:");  console.info(data);};emitter.on("food", methodB);//模块C中触发事件emitter.fire("food", "饭来了");//模块B中移除事件emitter.remove("food", methodB);//模块C中再次触发事件emitter.fire("food", "饭又来了");

执行结果如下:

模块 A 接受到 food 消息:

饭来了

模块 B 接受到 food 消息:

饭来了

模块 A 接受到 food 消息:

饭又来了

js 组件模块的通讯方式一般分为3种(直接通讯、通过父组件通讯、通过事件模块通讯)。观察者模式用于模块、组件之间通讯,通过提供统一的模式进行事件订阅、事件发布,从而达到模块、组件之间解耦,提高代码的可维护性

关于Javascript中原型模式是怎样的 就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

0