The prototype

Every time an object (except null) is created in javascript, another object is associated with it. This associated object is a stereotype from which each object inherits properties.

1.prototype

    function Person(age){
    	this.age = age;
    }
    Person.prototype.Name = 'test';
    var person = new Person();
    console.log(person.Name)    // 'test'
Copy the code

As you can see here, each function has a prototype property that points to the function’s prototype object. The prototype of a function can be obtained through the.prototype property, which can read or set the properties of its prototype object.

2.__ proto__

    function Person(){}
    var person = new Person();
    console.log(person.__proto__ === Person.prototype);   // true
Copy the code

Every object (other than NULL) has a __proto__ attribute that fetches the prototype of that object

3.constructor

    function Person(){}
    console.log(Person === Person.prototype.constructor);  //true
Copy the code

Each stereotype has a constructor attribute pointing to the constructor associated with it.

So the prototype’s relationship between functions and objects is as follows:

Prototype chain

4. Expand the prototype of the prototype

Given the above points, a prototype is an object. What is the prototype of a prototype?

    function Person(){}
    console.log(typeof(Person.prototype.__proto__))   //Object
Copy the code

From this we can see that the prototype of the prototype is also an object, so what is the prototype of the prototype of the prototype object

    var obj = new Object()
    console.log(obj.__proto__.__proto__);    //null
Copy the code

So the prototype of the object’s prototype is NULL, and at this point the association ends. So the diagram of the entire prototype chain is as follows

Several inheritance methods and advantages and disadvantages

Suppose a public parent class Person with the following attribute methods:

    function Person(name){
    	this.name = name || 'noName';
        this.sleep = function(){
        	console.log(this.name + 'I want to sleep');
        }
    }
    Person.prototype.eat = function(food){
    	console.log(this.name + 'I want to cook, especially' + food);
    }
Copy the code

1. Prototype chain inheritance

    function Woman(){}
    Woman.prototype = new Person();
    Woman.prototype.Name = Pretty Girl;
    let woman = new Woman();
Copy the code
  • Advantages:
    • This makes an example of a parent class a prototype for a subclass, which is easy to implement.
    • Any property or method added later by the parent class can be accessed by the child class.
    • Manipulate subclasses to modify properties in stereotypes.
  • Disadvantages:
    • To add a property or method to a stereotype, you must first create an instance.
    • No more inheritance
    • Cannot pass arguments to the parent constructor when creating a subclass instance

Constructor inheritance

    function Woman(name){
    	Person.call(this,name);
       this.name = name || 'No Name';
    }
    let woman = new Woman('xixi');
   console.log(woman.name, woman.sleep(), woman.eat());  // undefined, error (women. Eat is not a function)
Copy the code
  • advantages
    • The shortcoming of impassable parameters in prototype chain inheritance is solved.
    • Subclasses can inherit from more than one parent (using multiple Calls or apply)
  • disadvantages
    • Here woman is an instance of woman, but not an instance of Person, because the woman archetype doesn’t point to Person.
    • Attributes and methods (EAT) in the parent Person stereotype cannot be inherited.
    • Subclass Woman can inherit properties and methods from Person, but functions from Person cannot be reused, as shown in sleep().

3. Instance inheritance

   function Woman(name){
   		let instance = new Person();
        instance.name = name || 'no name';
        return instance
   }
   var women = new Woman();
Copy the code
  • advantages
    • There is no limit to how the call is made, either new Woman() or Woman() can be inherited.
  • disadvantages
    • Woman is an instance of Person, not woman
    • Multiple inheritance is not supported

4. Combinatorial inheritance

	function Woman(name){
    	Person.call(this,name);
        this.name = name || 'no name';
    }
    
    // Change the entire prototype chain
    Woman.prototype = new Person();
    Woman.prototype.constructor = Woman;
    let woman = new Woman();
Copy the code
  • advantages
    • Woman instance can get properties and methods of Woman as well as properties and methods of Person’s prototype object (eat)
    • Woman is an instance of subclass woman and of its parent class Person
    • To compensate for the disadvantage of pure construction inheritance, you can pass values to the parent class Person
    • You can reuse functions of all objects
  • disadvantages
    • The parent constructor is called twice, generating two instances and consuming a bit more memory.

6. Parasitic combination inheritance

	function Woman(name){
    	Person.call(this,name);
        this.name = name ||'No Name'; } (function(){
    	// Super has no instance method, which avoids creating two instances of the previous inheritance method
    	var Super = function(){};
        Super.prototype = Person.prototype;
        Woman.prototype = new Super();
    })
    Woman.prototype.constructor = Woman;
    
    let woman = new Woman();
Copy the code
  • advantages
    • On the advantage of combination inheritance, the problem of creating two instances is solved
  • disadvantages
    • complex