On prototype, prototype chain and several methods of inheritance

Posted by jamesh on Sun, 17 Nov 2019 16:08:14 +0100

There are several ways to create objects:

//Literal
var a = {name:'zhangsan'}
var b = new Object({name:'lisi'})
//Constructor
var M = function(name){
    this.name = name
}
var c = new M('wangwu)

//Object object creation
var d = {name:'xiaoliu'}
var e = Object.create(d)

 

As can be seen from the above figure, the instance object from the constructor new has a pointer of "proto". The prototype object that points to the constructor. Then there is a chain relationship with the prototype object of the constructor, and the prototype chain appears. Here we print out the following relationships:

That is to say, the instance object from M new -- > prototype prototype object of M constructor. The prototype object of the M constructor has a constructor constructor, which points to the constructor itself.

c instanceof M / / true uses instanceof to detect whether c is an instance object created by the constructor.

 

Here are several ways to inherit, compare the advantages and disadvantages.

1. Inherit by constructor

 function Father(){
            this.name = 'zhangsan'
        }
        Father.prototype.say = function(){
            console.log('I am father Prototype method of')
        }
        function Son(){
            Father.call(this)
            this.age = 18
        }
        var a = new Son()
        var b = new Father()
         console.log(b.say)       // function(){console.log('I'm the prototype method of father ')}
        console.log(a)          // Son   {name:'zhangsan',age:18} 
        console.log(a.say)    //undefiend

There is an instance object whose call inherits from Father.

The disadvantage is that you cannot inherit the properties or methods under the prototype.

2. Inheritance through prototype chain

        function Father() { 
            this.name = 'zhangsan'
            this.arr = [1,2,3]
         }
         function Son(){
             this.age = 18;
         }
         Son.prototype = new Father()
         console.log(new Son)   
         var a = new Son()
         var b = new Son()
         a.arr.push(4)
         console.log(a.arr)   //[1,2,3,4]
         console.log(b.arr)  //[1,2,3,4]

//As can be seen from the above code, there are disadvantages in implementing inheritance through this method,
//Instantiate two instance objects of Son. If there are properties of reference type in the parent class, they will be shared, which means one change and all changes.

3. Combination inheritance

  //3 mixed inheritance
        function Father() { 
            this.name = 'zhangsan'
            this.arr = [1,2,3]
        }
        function Son(){
            Father.call(this)
            this.age = 18
        }
        Son.prototype = new Father()
        var a =new Son()
        var b =new Son()
        a.arr.push(4)
        console.log(a.arr,b.arr)    //[1,2,3,4]  [1,2,3]
     //Although inheritance in this way solves the problem of being shared, the following problems arise. When instantiating Son, the constructor of the parent was called twice.

4. Another writing method of combination inheritance

 

function Father() { 
            this.name = 'zhangsan'
            this.arr = [1,2,3]
        }
        function Son(){
            Father.call(this)
            this.age = 18
        }
        Son.prototype = Father.prototype
        var a =new Son()
        var b =new Son()
        a.arr.push(4) 
        console.log(a.arr,b.arr)   //[1,2,3,4]  [1,2,3]
//This method solves the problem of calling the parent constructor twice, but there is a problem that the direction of the instance object is not clear from the child element new, and it is unknown whether it is in the parent or in the child element.

5 optimal inheritance method

function Father() { 
            this.name = 'zhangsan'
            this.arr = [1,2,3]
        }
        function Son(){
            Father.call(this)
            this.age = 18
        }
        Son.prototype = Object.create(Father.prototype)
        Son.prototype.constructor = Son 
        var a =new Son()
        var b =new Son()
        a.arr.push(4) 
        console.log(a.arr,b.arr)   //[1,2,3,4]  [1,2,3]
//It solves the problem that the constructor of instance object of child element points to unknown.

That's the personal understanding of archetype, archetypal chain, inheritance.