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.