Copy attributes

Copy a member of an object to the object that you want to inherit

Var superObj = {name: 'Li', age: 25, friends: [' xiaoyi ', 'xiaoyi '], showName: function(){alert(this.name); Var subObj = {}; // Start copying properties (use for... in... For (var I in superObj){subObj[I] = superObj[I]; } console.log(subObj) console.log(superObj)Copy the code

Existing problems:

If the inherited member is of reference type,

The members of the reference type are shared between the parent and child objects, meaning that changes will affect both the parent and child objects.

Prototype chain inheritance

Use an instance of a parent class as a prototype for a subclass

The parent class:

/ / 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);Copy the code

The 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:

1. Pure inheritance. An instance is an instance of both a subclass and a parent class

3. Simple and easy to implementCopy the code

Disadvantages:

1. 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. Multiple inheritance cannot be implemented 3. All properties from the prototype object are shared by all instances 4. Cannot pass arguments to the parent constructor when creating a subclass instance

Constructor inheritance

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).

The parent class:

/ / 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);Copy the code

The subclass:

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
Copy the code

Features:

1. Solve the problem of subclass instances sharing parent class reference attributes in 1

3. Can implement multiple inheritance (call multiple parent objects)

Disadvantages:

1. An instance is not an instance of a parent class, but an instance of a subclass

2. Only instance attributes and methods of the parent class can be inherited. Function reuse is not possible, each subclass has a copy of the parent class instance function, affecting performance

Combination of inheritance

By calling the superclass constructor, the attributes of the parent class are inherited and the advantages of passing arguments are retained. Then, functions can be reused by using the instance of the parent class as the prototype of the subclass

The parent class:

/ / 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);Copy the code

The subclass:

function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); / / repair the constructor to the prototype. The 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); // trueCopy the code

Features:

1. To remedy the defect of mode 2, you can inherit instance attributes/methods as well as prototype attributes/methods

2. An instance of both a subclass and a parent class 3. There is no reference attribute sharing problem 4. Parameters can be passed, the function can be reused

Disadvantages:

The parent constructor is called twice, generating two instances (the subclass instance hides the subclass prototype)

Parasitic combinatorial inheritance

In a parasitic manner, the instance attributes of the parent class are cut off, so that when a construct of the parent class is called twice, the two instance methods/attributes are not initialized, avoiding the disadvantages of combinatorial inheritance

The parent class:

/ / 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);Copy the code

The subclass:

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 Cat.prototype.constructor = Cat; // The constructor needs to be fixedCopy the code

Or:

The core of inheritance implementation is to assign the prototype of the parent class to the child class, and set the constructor to the child class, which not only solves the problem of useless parent class attributes, but also can correctly find the constructor of the child class.

function Cat(name){
  Animal.call(this);
  this.name = name || 'Tom';
}
 
Cat.prototype = Object.create(Animal.prototype, {
  constructor: {
    value: Cat,
    enumerable: false,
    writable: true,
    configurable: true
  }
})
 
// 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 
Copy the code

Features:

perfect

Disadvantages:

Implementation is complicated

The Class inheritance

In ES6, we can use class to implement inheritance, and it’s easy to implement. Extends indicates which parent class to inherit from, and super must be called in the subclass constructor. This code can be thought of as animal.call (this, name). A Class is essentially a function

The parent class:

/ / 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);Copy the code

The subclass:

Class Cat extends Animal {constructor(name){super(name); < br > this. Name = name | | 'Animal'; } } var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); //trueCopy the code