Prototype pattern: Refers to using prototype instances to point to the type of object to be created and creating new objects by copying those prototypes.

The real prototype inheritance, introduced as the latest version of the ECMAScript5 standard, uses the object.create method to create such objects. The method creates the specified Object, whose prototype has the specified Object (the first parameter Object passed by the method), Optionally, other specified properties can also be included. Such as the Object. The create (proto, [propertiesObject])

process

Prototype => new ProtoExam => clone to new Object;

Create a prototype => New a prototype instance => copy the prototype instance to the new object

  // Create a prototype and add some properties this.xxx to add
  function Person () {
    this.name = 'Uzi'
    this.sex = '21'
    this.age = 'male'
    this.getName=function () {
      return ` name:The ${this.name}`}}// The.prototype.xxx method is also available
  Person.prototype.getMsg = function () {
    return ` name:The ${this.name}Age:The ${this.age}Gender:The ${this.sex}`
  }
  
  // New a prototype instance
  const proto = new Person();  
  // Copy the prototype instance with object.create
  const person1 = Object.create(proto);
  const person2 = Object.create(proto);
  person2.name = 'Ming'
  person2.sex = '20'
  person2.age = 'male'
  console.log(person1.getName())  // Name: Uzi
  console.log(person2.getName())  // Name: Ming
  console.log(person1.getMsg())  // Name: Uzi, age: male, gender :21
  console.log(person2.getMsg())  Name: Ming, age: male, gender :20
Copy the code

This code also proves that the prototype hangs on the prototype chain of the instance, and modifying the instance does not affect the prototype, which is a deep copy

The prototype pattern is generally used when the abstract structure is complex, but the content composition is similar, the abstract content can be customized, and the new creation only needs to modify the original object to meet the requirements.

advantages

Methods are not recreated (as long as a new prototype instance is created)

Disadvantages:

  1. All properties and methods are shared
  2. Cannot initialize parameters

Object.create

define

Creates an object that has the specified stereotype and optionally contains the specified properties

Object.create(proto, [propertiesObject])

Proto: The prototype object of the newly created object

PropertiesObject: Optional. If it is not specified as undefined, it is the property descriptor and corresponding property name of the object to be added to the newly created object for enumerable properties (that is, properties defined by itself, rather than enumerated properties in its stereotype chain). These properties correspond to the second argument to Object.defineProperties().

use

1. Define the prototype object

  // Add the attribute method this.xxx
  function Person () {
    this.name = 'Uzi'
    this.sex = '21'
    this.age = 'male'
    this.getName=function () {
      return ` name:The ${this.name}`}}// Add attribute method.prototype.xxx
  Person.prototype.getMsg = function () {
    return ` name:The ${this.name}Age:The ${this.age}Gender:The ${this.sex}`
  }
Copy the code

2. UseObject.createCopies of the prototype

1. ToPerson.prototypeCreate an object
  const person1 = Object.create(Person.prototype, {
    position: {value: 'ADC'.writable: true}})console.log(person1.position)   // ADC
  console.log(person1.getMsg())   // Name :undefined, age :undefined, gender :undefined
  console.log(person1.getName())  // Uncaught TypeError: person1.getName is not a function

Copy the code

Person1 has the Person prototype method getMsg, but does not have the Person member attributes name, sex, age, and getName

2. InstantiatedPersonDo the prototype
  const proto = new Person();  // Instantiated Person
  const person2 = Object.create(proto, {
    position: { value: 'SUP'.writable: true}}); person2.name ='Ming'
  person2.sex = '20'
  person2.age = 'male'
  console.log(person2.position)  // SUP
  console.log(person2.getMsg())  Name: Ming, age: male, gender :20
  console.log(person2.getName())  // Name: Ming
Copy the code

Person2 is thus created with all member attributes of Person: Name, sex, age, getName, and getMsg prototype methods. And added a position read-only data property;

useObject.createImplementing subclass Inheritance

1. ToPerson.prototypeObject, asSonThe prototype of the
  function Son () {
    Person.call(this);   // The Person member attribute is not available otherwise
  }

  Son.prototype = Object.create(Person.prototype, {
    position: { value: 'son'}}); Son.prototype.sonMethod =function() {
    return this.name || this.position;
  }

  const son1= new Son()
  console.log(son1.position)    / / son
  console.log(son1.getMsg())    // Name: Uzi, age: male, gender :21
  console.log(son1.sonMethod()) // Uzi
  console.log(son1.getName())   // Name: Uzi
Copy the code
2. InstantiatedPersonObject, asSonThe prototype of the
  const proto = new Person();

  function Son () {
  }

  Son.prototype = Object.create(proto, {
    position: { value: 'son'}});const son1= new Son()
  console.log(son1.position)   / / son
  console.log(son1.getMsg())   // Name: Uzi, age: male, gender :21
  console.log(son1.getName())  // Name: Uzi
Copy the code

After Son is instantiated, you can get all the attributes and prototype methods of Person, and create a read-only data property position.

Object.createThe implementation of the

Object.prototype.create = function (obj) {
    if (Object.prototype.create) {
      return Object.prototype.create
    } else {
      function F () {
        F.prototype = obj; // Construct objects based on the parameters passed in
        return newF(); }}}Copy the code

This also shows that a new object is returned, a deep copy

Object.create, {}, new Object() contrast

Object.create specifies the prototype Object to copy. Object.create(null) does not have any prototype attributes. {}, new Object(), has the prototype attributes of the Object