Javascript design pattern prototype mode details

Javascript design pattern prototype mode details

1. Prototype mode

The prototype pattern is used to improve performance, reduce memory usage, and reuse code by sharing the properties and methods of an object prototype when creating an object.

Example 1

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

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

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

If you need to create 100 instances using the above code, you will need to create 100 config and 100 hello , and these two things are exactly the same in each instance.

Therefore, we can perform oil optimization by extracting common codes.

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

  this.config = config;

  this.hello = hello
}

This way, no matter how many Person objects are created, only one config and one hello need to be created. However, there are still problems such as global variables being polluted, config being modified by mistake, Person being highly coupled with other codes, and difficulty in code expansion and maintenance.

Therefore, optimization can be performed through prototyping.

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


The prototype diagram of this function when creating an instance is as follows:

Example 2

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

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

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

//This method will rewrite the prototype, causing the constructor to be lost and become Object().
//You can use Person.prototype.xx=yy to write, or re-specify 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);

The prototype diagram of this function when creating an instance is as follows:

Example 3

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

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

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

//This method will rewrite the prototype, causing the constructor to be lost and become 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 internal property comparison console.info(pA.hello == pB.hello); //false internal property comparison console.info(pA.say === pB.say); //true prototype method sharing pA.say("qq");
pB.say("qq");
console.info(pA.version === pB.version); //true prototype property sharing console.info(pA.version); //1.0
Person.prototype.version = 2.0; //Modify prototype shared properties console.info(pB.version); //2.0
console.info(new Person().version); //2.0

//Modify the prototype sharing method PersonB.prototype.say = function (arg) {
  console.info(`v2--- ${this.name} say ${arg}`);
};
pB.say("qq");
new Person("Person").say("ww");

Summarize:

js consumes more memory and takes a long time to create objects. You can reduce memory usage by reducing the creation of internal attributes.

The prototype mode uses the prototype feature of the javascript language to share the same properties, thereby reducing memory usage and improving object creation efficiency.

2. Observer Pattern

The observer pattern is used for communication between modules and components by providing a unified pattern for event subscription and event publishing. This achieves decoupling between modules and components and improves the maintainability of the code.

Communication methods between modules and components

Direct reference communication is used between modules and components

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

  letBrun: function () {
    //Directly reference moduleB
    moduleB.run();
  },
};

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

  letAsay: function () {
    //Directly reference moduleA
    moduleA.say("hello");
  },
};

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

Parent component communication is used between modules and components

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

Event module realizes communication

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

//Subscribe to resourcesEmitter.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)
}

//Unsubscribe resourcesEmitter.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();

//Register events in module A const methodA = (data) => {
  console.info("Module A received food message:");
  console.info(data);
};

emitter.on("food", methodA);

//Register events in module B const methodB = (data) => {
  console.info("Module B receives food message:");
  console.info(data);
};
emitter.on("food", methodB);

//Trigger event in module C emitter.fire("food", "Rice is coming");

//Remove event from module B emitter.remove("food", methodB);

//Trigger the event again in module C emitter.fire("food", "Rice is here again");

The execution results are as follows:

Module A receives the food message:

The meal is here

Module B receives the food message:

The meal is here

Module A receives the food message:

The meal is coming again

Summarize:

There are generally three ways for js component modules to communicate (direct communication, communication through parent components, and communication through event modules). The observer pattern is used for communication between modules and components. It provides a unified pattern for event subscription and event publishing, thereby decoupling modules and components and improving the maintainability of the code.

This is the end of this detailed article about the prototype pattern of Javascript design pattern. For more relevant Javascript prototype pattern content, please search 123WORDPRESS.COM's previous articles or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of JavaScript prototype and examples
  • JavaScript two pictures to understand the prototype chain
  • JavaScript Prototype Details
  • Detailed explanation of JavaScript prototype chain
  • JavaScript prototype and prototype chain details
  • Do you know what JavaScript prototype is?

<<:  Analysis of the operating principle and implementation process of Docker Hub

>>:  Analysis on how to solve the problem of Navicat Premium connecting to MySQL 8.0 and reporting error "1251"

Recommend

5 Ways to Send Emails in Linux Command Line (Recommended)

When you need to create an email in a shell scrip...

MySQL data type selection principles

Table of contents Small but beautiful Keep it sim...

Implementation of WeChat applet message push in Nodejs

Select or create a subscription message template ...

Docker installation and configuration image acceleration implementation

Table of contents Docker version Install Docker E...

Will Update in a Mysql transaction lock the table?

Two cases: 1. With index 2. Without index Prerequ...

Implementation of Docker packaging image and configuration modification

I have encountered many problems in learning Dock...

Understanding and solutions of 1px line in mobile development

Reasons why the 1px line becomes thicker When wor...

JavaScript implements random generation of verification code and verification

This article shares the specific code of JavaScri...

HTML+CSS to achieve cyberpunk style button

First look at the effect: Preface: I came up with...

idea combines docker to realize image packaging and one-click deployment

1. Install Docker on the server yum install docke...

How to submit a pure HTML page, pass parameters, and verify identity

Since the project requires a questionnaire, but th...

Vue implements the digital thousands separator format globally

This article example shares the specific code for...

Getting Started Guide to MySQL Sharding

Preface Relational databases are more likely to b...