preface
As a weakly typed object-oriented language, JS inheritance is also one of its very powerful features. So how do you implement inheritance in JS? Let’s wait and see.
To implement inheritance, then we must have a parent class, the code is as follows:
/ / define a Animal function Animal (name) {/ / attribute this. Name = name | | ‘Animal’; This.sleep = function(){console.log(this.name + ‘sleeping! ‘); } // animal.prototype. eat = function(food) {console.log(this.name + ‘eating:’ + food); }; 1. Prototype chain inheritance core: take the instance of the parent class as the prototype of the subclass
function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = ‘cat’;
// Test Code 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 features:
Very pure inheritance relationship, instance is the instance of the subclass, but also the instance of the parent class new prototype method/prototype attribute, subclass can access simple, easy to implement disadvantages:
To new properties and methods for the subclass, must be in the new Animal () such a statement is executed after, not on the constructor cannot achieve multiple inheritance from the prototype object reference properties are all instances Shared (see appendix code in detail: example 1) create a subclass instance, cannot be recommended to participate the superclass constructor index: ★★ (3, 4 two fatal defects)
Add: Thanks MMHS for pointing out. Defect 1 is not described correctly: you can add instance attributes to Cat instances in the Cat constructor. If new prototype properties and methods are added, they must be executed after statements like new Animal().
2. Construct the 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’; }
// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
[Fixed] When creating a subclass instance, you can pass arguments to the parent class. You can implement multiple inheritance (call multiple parent objects).
An instance is not an instance of the parent class, but an instance of a subclass can only inherit the instance attributes and methods of the parent class, but cannot inherit the prototype attributes/methods. Function reuse cannot be realized. Each subclass has a copy of the instance functions of the parent class, which affects performance.
3. Instance inheritance core: Add new features to the parent class instance and return it as a subclass instance
function Cat(name){ var instance = new Animal(); instance.name = name || ‘Tom’; return instance; }
// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false
There is no limit to how the call is made, and whether a new subclass () or subclass () returns an object with the same effect disadvantage:
Instances that are instances of parent classes, but not subclasses, do not support multiple inheritance
Function Cat(name){var animal = new animal (); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.name = name || ‘Tom’; }
// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
Disadvantages of supporting multiple inheritance:
Low efficiency, high memory footprint (because you need to copy the attributes of the parent class) cannot get the parent class’s non-enumerable methods (non-enumerable methods, cannot be accessed using for in)
5. Composite inheritance core: Inherits the attributes of the parent class and retains the advantages of parameter passing by calling the parent class construction, and then realizes function reuse by taking the parent class instance as the prototype of the subclass
function Cat(name){ Animal.call(this); this.name = name || ‘Tom’; } Cat.prototype = new Animal();
// Combinatorial inheritance also needs to be fixed.
Cat.prototype.constructor = Cat;
// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true
It can inherit instance attributes/methods and prototype attributes/methods that are both instances of subclasses and instances of parent classes. There is no reference attribute sharing problem. Functions can be reused by passing parameters.
The parent constructor is called twice, generating two instances (the subclass instance masks the subclass prototype).
6, parasitic combination inheritance core: through the parasitic way, cut off the instance attributes of the parent class, so that when calling the construction of the parent class twice, the two instance methods/attributes will not be initialized, to avoid the shortcomings of combination inheritance
function Cat(name){ Animal.call(this); this.name = name || ‘Tom’; } (function(){var Super = function(){}; Super.prototype = Animal.prototype; Cat.prototype = new Super(); }) ();
// Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //true
Thanks to the @blueDrink alert, this implementation does not fix constructor.
Cat.prototype.constructor = Cat; // We need to fix the constructor.
A perfect shortcoming:
★★★★ (To achieve complexity, deduct one star)