The implementation of JS inheritance
To implement inheritance, we need to have a parent class that looks like this:
/ / define a Animal function Animal (name) {/ / attribute this. Name = name | | 'Animal' / / instance methods this. Sleep = function () { Console. log(this.name + 'Sleeping! ')} // Animal.prototype.eat = function(food) {console.log(this.name + 'eating:' + food); };Copy the code
1. Prototype chain inheritance
Core: Use an instance of a parent class as a prototype for a subclass
function Cat(){}
Cat.prototype = new Animal();
Cat.prototype.name = 'cat';
var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); //true
console.log(cat instanceof Cat); //true
Copy the code
Features:
- Very pure inheritance, an instance is an instance of a subclass and an instance of a parent class
- New stereotype methods/attributes in the parent class that are accessible to all subclasses
- Simple and easy to implement
Disadvantages:
- To add attributes and methods to a subclass, you must specify the
new Animal()
Such statements are executed later and cannot be placed in the constructor - Multiple inheritance cannot be implemented
- All properties from the stereotype object are shared by all instances
- Cannot pass arguments to the parent constructor when creating a subclass instance
2. Structural inheritance
Core: Using the constructor of the parent class to enhance the instance of the child class is equivalent to copying the instance properties of the parent class to the child class (without using the stereotype).
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
Copy the code
Features:
- Fixed the problem of subclass instances sharing parent class reference attributes in 1
- When you create a subclass instance, you can pass parameters to the parent class
- Multiple inheritance can be implemented (call multiple parent objects)
Disadvantages:
- An instance is not an instance of a parent class, only an instance of a subclass
- Only instance properties and methods of the parent class can be inherited, not stereotype properties/methods
- Function reuse is not possible, each subclass has a copy of the parent class instance function, affecting performance
3. Instance inheritance
Core: Adds new features to the parent class instance and returns it as a subclass instance
function Cat(name){
var instance = new Animal();
instance.name = name || 'Tom';
return instance;
}
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // false
Copy the code
Features:
- There are no restrictions on how to call, either
New subclasses ()
orSubclasses ()
, the returned object has the same effect
Disadvantages:
- An instance is an instance of a parent class, not a subclass
- Multiple inheritance is not supported
Copy inheritance
function Cat(name){
var animal = new Animal();
for(var p in animal){
Cat.prototype[p] = animal[p];
}
this.name = name || 'Tom';
}
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // false
console.log(cat instanceof Cat); // true
Copy the code
Features:
- Support for multiple inheritance
Disadvantages:
- Low efficiency and high memory footprint (due to copying parent class attributes)
- Unable to get non-enumerable methods of the parent class (non-enumerable methods, not accessible using for in)
5. Combinatorial inheritance
Core: Inherits the attributes of the parent class and retains the advantages of passing arguments by calling the parent class constructor, and then implements function reuse by using the parent class instance as a subclass prototype
function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); // true
Copy the code
Features:
- To remedy the weakness of approach 2, you can inherit instance properties/methods as well as stereotype properties/methods
- Both an instance of a subclass and an instance of a superclass
- There is no reference property sharing problem
- Can pass the cords
- Function reuse
Disadvantages:
- The parent constructor is called twice, generating two instances (the subclass instance hides the subclass prototype)
6. Parasitic combination inheritance
Core: By parasitic way, the instance attributes of the parent class are cut off, so that when the constructor of the parent class is called twice, the two instance methods/attributes are not initialized, avoiding the disadvantages of combinative inheritance
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } (function(){var Super = function(){}; Super.prototype = Animal.prototype; Cat.prototype = new Super(); }) (); var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true Cat.prototype.constructor = Cat;Copy the code
Features:
- perfect
Disadvantages:
- Implementation is complicated