The introduction

The easiest way to create a custom Object is to create an instance of an Object and then add properties and methods to it. Early developers often used this pattern to create objects, but Object literals became the preferred method. Although methods of object constructors or object literals can be used to create objects, these methods create many objects using the same interface, resulting in a lot of repetitive code. In order to solve this problem, people began to use a variety of patterns to create objects, in these patterns, generally it is recommended to use four kinds of ways, including the constructor model, prototype model, constructors and prototypes portfolio model, dynamic prototype model, use other ways, including factory pattern, parasitic structure letter d/a, err on the side of the constructor mode usually use less. The most commonly used and recommended of these approaches are composite and dynamic prototyping. Here are the advantages and disadvantages of each mode:

  • The advantage of the factory pattern is that it does solve the problem of creating multiple similar objects, but it does not solve the problem of object recognition, that is, not knowing which object is creating the instance (constructor), because all instances are created by Object;

  • The biggest advantage of the constructor pattern is that the class of object instances (its constructors) can be identified by Contructor or Instanceof, but each method is created once each instance is created;

  • Prototype pattern is the instance of the advantages of the method is Shared, all instances of the same point in the same way, so that each time you create an instance method does not create again, but it is also a weakness, archetypal pattern of all the properties and methods are Shared in such a two problem is there is no way to create instance attributes and methods, Second, when an instance changes the data in a property, other instances will change as well, and it cannot pass arguments like a constructor can.

  • Constructors and prototypes advantage sharing is the sharing of combination mode, the private, the private box constructor defined all non-functional attributes of an object, method and the Shared attributes are defined with the prototype method, as a result, each instance will have their own a copy of the instance attributes, but at the same time and share with the reference of the method, maximum limit to save memory. In addition, this blending pattern supports passing parameters to constructors; This hybrid pattern of constructors and stereotypes is currently the most widely used and recognized method of creating defined types in ECMAScript.

    Note that the composite pattern addresses the drawback of the prototype pattern not being able to pass parameters and the constructor pattern not being able to share methods.

  • The dynamic prototype pattern is highly recommended today, but be careful not to rewrite the prototype with object literals

  • The parasitic constructor pattern is basically the same as the factory pattern, except that it has the new operator and therefore does not recognize objects, or the category of instances, which is not recommended

  • The secure constructor pattern is suitable for some secure environments. A secure object is an object that has no common attributes, whose methods do not reference this, and which cannot recognize the type of the object. This method is not recommended

The factory pattern

function Person(name) {
  var o = new Object(a); o.name = name; o.say =function() {
    alert(this.name);
  }
  return o;
}
var person1 = Person("yawei");
Copy the code

Disadvantages:

  1. Object is unrecognizable and all instances point to a stereotype; Objects cannot be identified by constructor because they come from Object.
  2. All say methods are the same every time an object is created through Person, but they are stored multiple times, wasting resources.

Constructor pattern

function Person() {
  this.name = 'hanmeimei';
  this.say = function() {
    alert(this.name)
  }
}

var person1 = new Person();
Copy the code

Advantages:

  1. The class of object instances can be identified by constructor or instanceof
  2. Object instances can be created using the new keyword, much like in OO languages

Disadvantages:

  1. The say method on multiple instances achieves the same effect, but is stored multiple times.

Note:

  1. Constructor mode implicitly returns at the endreturn thisSo in the absence of new, properties and methods are added to the global object, and the browser side to the Window object.
  2. It can also be based onreturn thisThe call or apply feature specifies this. This helps a lot later on in inheritance.

The prototype pattern

function Person() {}
Person.prototype.name = 'hanmeimei';
Person.prototype.say = function() {
  alert(this.name);
}
Person.prototype.friends = ['lilei'];

var person1 = new Person();
Copy the code

Advantages:

  1. The say method is shared, and all instances point to the same say method.

  2. Methods and properties of the prototype object can be added dynamically and reflected directly on the object instance.

    var person1 = new Person()
    Person.prototype.showFriends = function() {
      console.log(this.friends)
    }
    person1.showFriends()  //['lilei']
    Copy the code

Disadvantages:

  1. A problem occurs when a reference is present, as shown in the following code:

    var person1 = new Person();
    var person2 = new Person();
    person1.friends.push('xiaoming');
    console.log(person2.friends)  //['lilei', 'xiaoming']
    Copy the code

    Because js assignments to reference types store addresses in variables, the friends attribute for person1 and person2 points to the same storage area.

  2. The first call to say or name will be searched twice. The first call will look for say on the instance, and if it doesn’t find say, it will look for say on the Person.prototype object.

  3. All methods are shared; there is no way to create instance properties and methods, and no way to pass arguments like constructors.

Note:

  1. The first problem is that assigning to Person.prototype directly from object literals causes constructor to change, so it needs to be set manually. The second problem is that assigning to Person.prototype directly from object literals does not apply to previously created object instances

    var person1 = new Person()
    Person.prototype = {
    	name: 'hanmeimei2'.setName: function(name){
          this.name = name
      	}
    }
    
    person1.setName()   //Uncaught TypeError: person1.set is not a function(...) TypeError: person1.
    Copy the code

    This is because object instances and object prototypes are linked directly through a pointer, which is an internal property [[Prototype]] and can be accessed via __proto__. We’ve changed the address to which Person.prototype points via the object literal, but the __proto__ of the object instance hasn’t been updated with it, so the instance is still accessing the original Person.prototype. It is not recommended to change the Person.prototype property in this way

Constructor and stereotype composition patterns

function Person(name) {
  this.name = name
  this.friends = ['lilei']
}
Person.prototype.say = function() {
  console.log(this.name)
}

var person1 = new Person('hanmeimei')
person1.say() //hanmeimei
Copy the code

Advantages:

  1. Addresses the shortcomings of the stereotype pattern for reference objects
  2. Solved the drawback of the prototype pattern not being able to pass parameters
  3. Resolved the drawback that constructor patterns cannot share methods

Disadvantages:

  1. Same as note 1 in the prototype pattern

Dynamic prototype pattern

function Person(name) {
  this.name = name
    // Check whether say is a function
    // The sayName method is actually only added to the prototype when it was not created the first time
    If () {if () {if () {if () {if () {if () {if () {if ();
// We can use the constructor to bind the scope of the new object to the constructor. If we use the constructor, we can create a new object and break the connection.
  if(typeof this.say ! ='function') {
    Person.prototype.say = function(
    alert(this.name)
  }
}
Copy the code

Advantages:

  1. The prototype object can be modified the first time the constructor is called
  2. Modifications can be made in all instances

** Cons: ** The Little Red Book says this is perfect…

Note:

  1. Just check for a method or property that should exist after execution. Suppose you define many other methods besides :say, such as sayBye, cry, smile, and so on. All you need to do is put them in the if block for sayName.

    if (typeof this.sayName ! ="function") {
        Person.prototype.sayName = function() {... }; Person.prototype.sayBye =function() {... }; Person.prototype.cry =function() {... }; . }Copy the code
  2. Prototype objects cannot be modified with object literals

Parasitic constructor pattern

function Person(name) {
  var o = new Object()
  o.name = name
  o.say = function() {
    alert(this.name)
  }
  return o
}

var peron1 = new Person('hanmeimei')
Copy the code

Advantages:

  1. Basically the same as factory mode, except for the new operator

Disadvantages:

  1. As with the factory pattern, instance classes cannot be distinguished

Stable structural model

function Person(name) {
  var o = new Object()
  o.say = function() {
    alert(name)
  }
}

var person1 = new Person('hanmeimei');
person1.name  // undefined
person1.say() //hanmeimei
Copy the code

Advantages:

  1. Security, then, seems to be a private variable that can only be accessed through the say method. A secure object is an object that has no public wakeup and whose methods do not refer to this.

Disadvantages:

  1. As with the factory pattern, instance classes cannot be distinguished

Reference article:

Objects in JavaScript, how to create objects, 7 modes to create objects

A person needs eight ways to create objects in object JS

Creation object of reading notes