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

Summary of several situations in which MySQL indexes fail

1. Indexes do not store null values More precisel...

How to completely uninstall mysql under CentOS

This article records the complete uninstallation ...

Detailed explanation of using split command to split Linux files

A few simple Linux commands let you split and rea...

Examples of preview functions for various types of files in vue3

Table of contents Preface 1. Preview of office do...

Detailed explanation of .bash_profile file in Linux system

Table of contents 1. Environment variable $PATH: ...

Full analysis of Vue diff algorithm

Table of contents Preface Vue update view patch s...

How does Vue solve the cross-domain problem of axios request front end

Table of contents Preface 1. Why do cross-domain ...

Implementation of adding remark information to mysql

Preface Some people have asked me some MySQL note...

nginx solves the problem of slow image display and incomplete download

Written in front Recently, a reader told me that ...

Four practical tips for JavaScript string operations

Table of contents Preface 1. Split a string 2. JS...

HTML 5 Preview

<br />Original: http://www.alistapart.com/ar...

Detailed example of using case statement in MySQL stored procedure

This article uses an example to illustrate the us...

JavaScript event capture bubbling and capture details

Table of contents 1. Event Flow 1. Concept 2. DOM...

Incredible CSS navigation bar underline following effect

The first cutter in China github.com/chokcoco Fir...