JS object oriented basic explanation of of factory mode constructor mode prototype mode mixed mode dynamic prototype mode

  • 2020-03-30 03:42:40
  • OfStack

What is object orientation? Object orientation is an idea! (nonsense).

Object orientation treats all the key modules in a program as objects, and the modules have properties and methods. In this way, if we encapsulate some properties and methods, it will be very convenient to use in the future, but also can avoid tedious and repetitive work. Next I'll show you the object-oriented implementation of JS.

  The factory pattern

The factory pattern is a well-known design pattern in software engineering, and since classes cannot be created in ECMAScript, objects are created in a specific interface using functional encapsulation. The method is very simple, that is, in the function to create an object, give the object attributes and methods and return the object.


function createBlog(name, url) {
  var o = new Object();
  o.name = name;
  o.url = url;
  o.sayUrl= function() {
    alert(this.url);
  }
  return o;
}

var blog1 = createBlog('wuyuchang', '//www.jb51.net/');

As you can see, the factory pattern is implemented in a very simple way, which solves the problem of creating multiple similar objects, but the factory pattern cannot recognize the type of Object, because all of them are objects, unlike Date, Array, and so on. Therefore, the constructor pattern appears.

Constructor pattern

Constructors in ECMAScript can create specific types of objects, similar to Array, Date, and other native JS objects. The implementation method is as follows:


function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = function() {
    alert(this.url);
  }
}

var blog = new Blog('wuyuchang', '//www.jb51.net/');
console.log(blog instanceof Blog);  // true .   judge blog Whether it is Blog , which solves the problem of not being able to in factory mode 

This example differs from the factory model in many ways, except for the function names:

Function names start with capital letters (although the standard does not strictly require capital letters, it is customary for constructors to start with capital letters
Create object not shown
Attributes and methods are directly assigned to this object
No return statement
Create an object using new
Object recognition (this is where the constructor pattern is superior to the factory pattern)

Constructor, though useful, is not without faults, using the constructor's biggest problem is that each time you create an instance to create a method (in theory, each time you create the object object's properties are different, and the method of object is the same), but there is no need to create exactly the same way twice, so we can function will be moved to the outside of the object (maybe some children's shoes have see faults, SHH!) .


function Blog(name, url) {
  this.name = name;
  this.url = url;
  this.alertUrl = alertUrl;
}

function alertUrl() {
  alert(this.url);
}

var blog = new Blog('scjb51', 'http://sc.jb51.net/'),
  blog2 = new Blog('jb51', '//www.jb51.net/');
blog.alertUrl();  // http://sc.jb51.net/
blog2.alertUrl();  // //www.jb51.net/

We will alertUrl set to global function, so that the blog and blog2 access will have the same function, but the problem again, in the global scope defines a real want blog use function, according to let the global scope some worthy of the name, more is unacceptable in the global scope defines many only for the use of a particular object, the method of waste of space, clearly lost the object-oriented encapsulation, so you can through the prototype to solve the problem.

The prototype pattern

Each function we create has a prototype property, which is a pointer to an object whose purpose is to contain properties and methods that can be Shared by all instances of a particular type. The advantage of using a prototype object is that all instances of the object share the properties and methods it contains.


function Blog() {
}

Blog.prototype.name = 'wuyuchang';
Blog.prototype.url = 'http://tools.jb51.net/';
Blog.prototype.friend = ['fr1', 'fr2', 'fr3', 'fr4'];
Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend );
}

//The following is the test code
var blog = new Blog(),
  blog2 = new Blog();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4
blog2.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2,fr3,fr4

blog.name = 'wyc1';
blog.url = 'http://***.com';
blog.friend.pop();
blog2.name = 'wyc2';
blog2.url = 'http://+++.com';
blog.alertInfo();  // wyc1http://***.comfr1,fr2,fr3
blog2.alertInfo();  // wyc2http://+++.comfr1,fr2,fr3

Prototype model is not without its drawbacks, first of all, it omits the constructor initialization parameter this link, the results have been obtained by default all instances of the same attribute values, this is very inconvenient, but it is not the prototype of the biggest problems, archetypal pattern caused by the nature of the biggest problem lies in the sharing, the sharing, so therefore modified the references an instance, another also change the references. So we often don't use stereotypes alone, but instead combine the stereotype pattern with the constructor pattern.

Mixed mode (prototype mode + constructor mode)


function Blog(name, url, friend) {
  this.name = name;
  this.url = url;
  this.friend = friend;
}

Blog.prototype.alertInfo = function() {
  alert(this.name + this.url + this.friend);
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net/', ['fr1', 'fr2', 'fr3']),
  blog2 = new Blog('wyc', 'http://**.com', ['a', 'b']);

blog.friend.pop();
blog.alertInfo();  // wuyuchanghttp://tools.jb51.net/fr1,fr2
blog2.alertInfo();  // wychttp://**.coma,b

Dynamic prototype pattern

The dynamic stereotype pattern encapsulates all the information in the constructor, and by initializing the stereotype in the constructor (only when the first object is instantiated), this can choose whether the stereotype needs to be initialized by determining whether the method is valid.


function Blog(name, url) {
  this.name = name;
  this.url = url;

  if (typeof this.alertInfo != 'function') {
    //This code was executed only once
    alert('exe time');
    Blog.prototype.alertInfo = function() {
      alert(thia.name + this.url);
    }
  }
}

var blog = new Blog('wuyuchang', 'http://tools.jb51.net'),
  blog2 = new Blog('wyc', 'http:***.com');

As you can see in the above example, the window pops up only once, 'exe time', that is, when the blog is initialized, so blog2 does not need to initialize the prototype, which is perfect for creating objects using this pattern.

This blog post is based on the 3rd edition of "link: #", but the language has been simplified and the examples have been rewritten. If you don't understand anything, please leave a comment and the author will update the blog.


Related articles: