1. Prototype chain inheritance
Principle: set the prototype of the subclass directly as the instance of the parent class
Disadvantages: because the subclass only makes one prototype change, all instances of the subclass save the value of the same parent class.
When modifying a value on a subclass object, if it is a modified value of the original type, a new value will be created on the instance;
However, if it is a reference type, it will modify the reference type in the only parent instance on the subclass, which will affect all subclass instances
function Parent() { this.name = "parent"; this.arr = [1, 2, 3]; } function Child() { this.type = "child"; } Child.prototype = new Parent(); var c1 = new Child(); var c2 = new Child(); c1.__proto__ === c2.__proto__;
2. Constructor inheritance
Use parent. In the constructor The method of call (this) inherits the parent property.
Principle: run this of the subclass through the constructor of the parent class
Disadvantages: the properties and methods on the Parent prototype chain are not inherited by subclasses
function Parent(name, id){ this.id = id; this.name = name; this.printName = function(){ console.log(this.name); } } Parent.prototype.sayName = function(){ console.log(this.name); }; function Child(name, id){ Parent.call(this, name, id); // Parent.apply(this, arguments); } var child = new Child("jin", "1"); child.printName(); // jin child.sayName() // Error
3. Combinatorial inheritance
call inheritance and prototype chain inheritance are used in the composite constructor.
Principle: use parent in subclass constructor call(this); You can inherit the properties and methods bound on this written in the parent class constructor;
Using child The prototype = new parent() method can inherit various properties and methods hung on the parent class prototype
Disadvantages: the parent class constructor is executed once in the subclass constructor and again when the subclass binds the prototype
function Parent(name, id){ this.id = id; this.name = name; this.list = ['a']; this.printName = function(){ console.log(this.name); } } Parent.prototype.sayName = function(){ console.log(this.name); }; function Child(name, id){ Parent.call(this, name, id); // Parent.apply(this, arguments); } Child.prototype = new Parent(); var child = new Child("jin", "1"); child.printName(); // jin child.sayName() // jin var a = new Child(); var b = new Child(); a.list.push('b'); console.log(b.list); // ['a']
4. Prototype inheritance
Principle: similar to object Create, wrap an object with a function, and then return the call of the function. The function becomes an instance or object that can add attributes at will. As a result, the sub object is__ proto__ Point to parent object
Disadvantages: shared reference types
var parent = { names: ['a'] } function copy(object) { function F() {} F.prototype = object; return new F(); } var child = copy(parent);
5. Parasitic inheritance
Principle: secondary packaging, prototype inheritance and expansion
Advantage: new properties and methods can be added
function createObject(obj) { var o = copy(obj); o.getNames = function() { console.log(this.names); return this.names; } return o; }
6. Parasitic combinatorial inheritance
Principle: improve combinatorial inheritance and inherit the prototype by using the idea of parasitic inheritance
function inheritPrototype(subClass, superClass) { // Copy a prototype of the parent class var p = copy(superClass.prototype); // Modified constructor p.constructor = subClass; // Set subclass prototype subClass.prototype = p; } function Parent(name, id){ this.id = id; this.name = name; this.list = ['a']; this.printName = function(){ console.log(this.name); } } Parent.prototype.sayName = function(){ console.log(this.name); }; function Child(name, id){ Parent.call(this, name, id); // Parent.apply(this, arguments); } inheritPrototype(Child, Parent);