This article has participated in the activity of “New person creation Ceremony”, and started the road of digging gold creation together.

As for the implementation of inheritance, there are several, I have summarized, code examples and advantages and disadvantages summary.

1. Prototype chain inheritance

Implementation example

Function Animal () {enclosing superType = 'Animal'. This name = 'name' | | 'animals' / / instance methods this. Sleep = function () { Console. log(this.name + 'sleeping ')}} // Animal.prototype.eat = function (food) {console.log(this.name +' eating '+ Food)} function Dog(name) {this.name = name} Implements the prototypal inheritance t prototype = new Animal () constructor / / the Dog pointing in the direction of their own t prototype. The constructor = Dog var doggie = new Dog (" wangcai ") Console. log(doggie.supertype)//Animal doggie.sleep()// Wangcai is sleeping doggie.eat(' bones ')// Wangcai is eating bonesCopy the code

Understand prototype inheritance in one picture

The original Dog constructor’s prototype pointed to Dog’s prototype object, but now points to Animal’s instance object. That is, the prototype of the Dog constructor is an instance of Animal.

advantages

  1. Implementation is simple, just need to set the prototype of the subclass as the instance of the parent class
  2. Properties and functions in the parent class prototype chain can be accessed directly through instances of subclasses

disadvantages

  1. All instances of a subclass will share the attributes of the parent class, which leads to a problem: if an instance of a subclass changes the value of an attribute of the parent class China as a reference type, it will affect the values of other instances.
  2. When creating an instance of a subclass, arguments cannot be passed to the constructor of the parent class. Through thenewWhen the operator creates an instance of a subclass, it calls the subclass’s constructor, which does not have an associated operation with the parent class, so it cannot pass arguments to the parent class’s constructor.
  3. When adding a property or method to a subclass’s prototype object, make sure to put it inStudent.prototype=new PersonAfter the statement.

For example,

Function Person() {this.emotion = [" eat ", "sleep "," study "]; } function Studnet(id) {this.id = id; Prototype = new Person(); Add the study method to Student's Prototype. Studnet.prototype.study = function () {console.log(" study hard, work hard "); }; Studnet.prototype = new Person(); Studnet.prototype.constructor = Studnet; var stu1 = new Studnet(1001); stu1.study(); //stu1.study is not a functionCopy the code

Studnet.prototype = new Person(); This line of code overwrites Student’s prototype object, so the Study method is invalid.

Modify the

Function Person() {this.emotion = [" eat ", "sleep "," study "]; } function Studnet(id) {this.id = id; } studnet. prototype = new Person(); Studnet.prototype.constructor = Studnet; Studnet.prototype=new Person studnet.prototype. study = function () {console.log(" study hard, work hard "); }; var stu1 = new Studnet(1001); stu1.study();Copy the code

Constructor inheritance

In the constructor of a subclass, the apply() method or call() method calls the constructor of the parent class to implement inheritance.

Implementation example

Function Person() {this.emotion = [" eat ", "sleep "," study "]; } function Studnet(id) {this.id = id; / / student id Person. Call (this); } var stu1 = new Studnet(1001); var stu2 = new Studnet(1002); Stu1.emotion. Push (" Play the game "); console.log(stu1.emotion); / / / "eat", "sleeping", "learning", "playing games"] the console. The log (stu2. Emotion); // [" eat ", "sleep "," study "]Copy the code

As you can see, the STU1 object adds data to the emotion array without affecting the STU2 object.

advantages

  1. As passed in the construction of a subclasscallChanges in the parent classthisPointing causes attributes or methods defined in the parent constructor to be assigned to subclasses so that each instance of the generated subclass has those attributes and methods. And they do not affect each other, even for reference types.
  2. When creating an instance of a subclass, you can pass arguments to the constructor of the parent class.

disadvantages

  1. A subclass can only inherit properties and methods from instances of its parent class, not from prototype objects of its parent class.
  2. Add an instance method to the constructor of the parent class, and the corresponding child class has that instance method, but the problem is that for every instance of a child class, there is an instance method in the parent class, which results in a large memory footprint.

3. Copy inheritance

Copy inheritance refers to creating an instance of a parent class and then passing it through for… In to iterate over all attributes and methods in the parent class instance and assign them in turn to the child class instance, while assigning attributes and functions on the prototype to the child class instance.

Implementation example

Function Person(age) {this.emotion = [" eat ", "sleep "," study "]; function Person(age) {this.emotion = [" eat ", "sleep "," study "]; // this. Age = age; This. Study = function () {console.log(this.id + "this "); }; } person.prototype. run = function () {console.log(this.id + "id"); }; function Studnet(id, age) { var person = new Person(age); For (var key in person) {if (person.hasownProperty (key)) {this[key] = person[key]; } else {studnet. prototype[key] = person[key]; This.id = id; this.id = id; } var student = new Studnet(1001, 21); student.study(); student.run();Copy the code

In the code above, you create a parent class Person, specify instance attributes and instance methods in that class, and add methods to its prototype object.

In the Studnet subclass, you first create an instance of the parent class Person, and then pass the for… If the return value of person.hasownProperty (key) is false, it means that the property and method are obtained on the prototype object of the parent class, so it should also be added to the prototype property of the subclass. A property or method on a native object that becomes a subclass.

advantages

First: you can implement passing parameters to constructors in the parent class.

Second, the ability to enable subclasses to inherit instance properties, instance methods, and properties and methods from the parent class.

disadvantages

All attributes and methods of the parent class need to be copied by the child class, so it consumes memory.

4. Combinatorial inheritance

The core idea of combinatorial inheritance is to combine constructor inheritance and prototype inheritance.

Implementation example

Function Person(age) {this.emotion = [" eat ", "sleep "," study "]; function Person(age) {this.emotion = [" eat ", "sleep "," study "]; // this. Age = age; This. Study = function () {console.log(this.id + "this "); }; } person.prototype. run = function () {console.log(this.id + "id"); }; Function Studnet(id, age) {// Constructor inherits person.call (this, age); this.id = id; Studnet.prototype = new Person(); Studnet.prototype.constructor = Studnet; var student = new Studnet(1001, 21); student.run(); Console. log(" hobby is :" + student.emotion);Copy the code

advantages

  1. Prototype = new Person(); person.call (this,ge); studnet.prototype = new Person(); You can bind properties and functions from the parent class’s prototype object to Student’s prototype object.

  2. Arguments can be passed to the constructor of the parent class.

disadvantages

The main disadvantage of composite inheritance is that instance attributes of the parent class are bound twice.

The first is a call to the parent constructor in the subclass constructor using the call() function to bind instance properties and methods.

The second time we overwrote the prototype property, we performed a new Person() operation, here we call the parent constructor again, complete the property binding operation.

So in the whole process of composite inheritance, the properties and methods of the parent class instance are bound twice. One thing to note here, of course, is that binding instance properties and methods in the parent class via the call() function takes precedence over rewriting prototype. In other words, the first method overrides the second method

Function Person(age) {this.emotion = [" eat ", "sleep "," study "]; function Person(age) {this.emotion = [" eat ", "sleep "," study "]; // this. Age = age; This.study = function () {console.log(this.id + ""); }; } person.prototype. run = function () {console.log(this.id + "id"); }; // prototype method person.prototype. study = function () {console.log(this.id + "iD "); }; function Studnet(id, age) { Person.call(this, age); this.id = id; } studnet.prototype = new Person(); Studnet.prototype.constructor = Student; var student = new Studnet(1001, 21); student.run(); Console. log(" hobby is :" + student.emotion); student.study(); // Call the instance method student of the parent classCopy the code

5. Parasitic combination inheritance

Implementation example

Function Person(age) {this.emotion = [" eat ", "sleep "," study "]; function Person(age) {this.emotion = [" eat ", "sleep "," study "]; // this. Age = age; This. Study = function () {console.log(this.id + "this "); }; } person.prototype. run = function () {console.log(this.id + "id"); }; Person. Prototype. study = function () {console.log(this.id + "iD "); }; function Studnet(id, age) { Person.call(this, age); this.id = id; Function Super() {} //Super. Prototype the prototype object points to person.prototype super. prototype = person.prototype; The prototype object points to an instance of Super, thus removing the instance attribute of the Person parent class. Studnet.prototype = new Super(); Studnet.prototype.constructor = Studnet; var student = new Studnet(1001, 21); student.run(); Console. log(" hobby is :" + student.emotion); student.study();Copy the code

In the code above, we create a Super constructor that points the super. prototype prototype to Person.prototype and assigns the Super object to Student.prototype, removing the instance attribute of the Person parent class.

Parasitic combinatorial inheritance solves the problem of combinatorial inheritance.

Ordinary implementations can use either composite inheritance or parasitic composite inheritance.