Complete high-frequency question bank warehouse address: github.com/hzfe/awesom…

The full frequency question bank reading address: febook.hzfe.org/

Issues related to

  • ES5 and ES6 inheritance issues

  • Prototype chain concept

Answer key points

The stereotype chain inheritance constructor inherits ES6 class inheritance

Inheritance is when a subtype has the properties and behavior of its parent type, allowing code to be reused and separated by design. Inheritance in JavaScript is implemented primarily through prototype chains and constructors. Common inheritance methods include: ES6 class inheritance, prototype chain inheritance, parasitic combination inheritance, etc.

Knowledge depth

1. The prototype chain

The essence of prototype chain is to extend the prototype search mechanism. Each instance object has a private attribute __proto__. This property points to the prototype object of its constructor. The __proto__ of this prototype object can also refer to the prototype of other constructors. Layer up until an object’s __proto__ points to null. Null, by definition, has no prototype and serves as the last link in the prototype chain.

When trying to access an Object’s properties, it searches not only for that Object, but also for the prototype of that Object and the prototype of that Object’s prototype, working its way up until it finds an attribute with a matching name or until the linked list ends (Object.prototype.__proto__ === null).

2. Prototype chain inheritance

The idea of stereotype chain inheritance: one reference type inherits the properties and methods of another.

function SuperType() { this.b = [1, 2, 3]; } function SubType() {} SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; var sub1 = new SubType(); var sub2 = new SubType(); Sub1.b.paush (4); sub1.b.paush (4); console.log(sub1.b); / / [1, 2, 3, 4] the console. The log (sub2. B); // [1,2,3,4] console.log(sub1 instanceof SuperType); // trueCopy the code

Advantages:

  1. New stereotype methods/attributes in the parent class that are accessible to all subclasses.

  2. Simple and easy to implement.

Disadvantages:

  1. Multiple inheritance cannot be implemented.

  2. Because reference values in the stereotype are shared, changes on the instance directly affect the stereotype.

  3. Cannot pass arguments to the parent constructor when creating a subclass instance.

3. Constructor inheritance

The idea of constructor inheritance: the subtype constructor calls the parent class’s constructor so that all attributes that need to be inherited are defined on the instance object.

function SuperType(name) { this.name = name; this.b = [1, 2, 3]; } SuperType.prototype.say = function () { console.log("HZFE"); }; function SubType(name) { SuperType.call(this, name); } var sub1 = new SubType(); var sub2 = new SubType(); Var sub3 = new SubType("Hzfe"); sub1.say(); // Constructor inheritance does not access the prototype chain, say method cannot call console.log(sub3.name); // Hzfe sub1.b.push(4); Console. log(sub1.b); console.log(sub1.b); / / [1, 2, 3, 4] the console. The log (sub2. B); // [1,2,3] console.log(sub1 instanceof SuperType); // falseCopy the code

Advantages:

  1. The problem that subclass instances share parent reference attributes in prototype chain inheritance is solved.

  2. Arguments can be passed to the superclass constructor in a subtype constructor.

  3. You can implement multiple inheritance (call multiple parent objects).

Disadvantages:

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

  2. Only instance properties and methods of the parent class can be inherited, not stereotype properties and methods.

  3. Function reuse is not possible, each subclass has a copy of the parent class instance function, affecting performance.

4. Combinatorial Inheritance (pseudo-classical inheritance)

The idea of composite inheritance: inheritance of prototype attributes and methods is realized by using prototype chains, and inheritance of instance attributes is realized by borrowing constructors.

function SuperType(name) { this.name = name; this.a = "HZFE"; this.b = [1, 2, 3, 4]; } SuperType.prototype.say = function () { console.log("HZFE"); }; function SubType(name) { SuperType.call(this, name); Prototype = new SuperType(); / / the first call SuperType SubType. The prototype. The constructor = SubType;Copy the code

Advantages:

  1. You can inherit instance properties/methods as well as stereotype properties/methods.

  2. There is no reference property sharing problem.

  3. Can pass the cords

  4. Function reuse

Disadvantages:

  1. The parent constructor is called twice (memory intensive), generating two instances.

Parasitic combinatorial inheritance

The idea of parasitic combinatorial inheritance is to borrow constructors to inherit properties and use hybrid prototype chain inheritance.

// Inside the function, the first step is to create a copy of the parent stereotype. The second step is to add the constructor attribute to the created copy, making up for the loss of the default constructor attribute due to overwriting. Finally, the newly created object (that is, the copy) is assigned to the prototype of the type. function inheritPrototype(subType, superType) { var prototype = Object.create(superType.prototype); Prototype. constructor = subType; // Add object subtype. prototype = prototype; } function SuperType(name) {this.name = name; } SuperType.prototype.sayName = function () { console.log(this.name); }; function SubType(name, num) { SuperType.call(this, name); this.num = num; } inheritPrototype(SubType, SuperType); SubType.prototype.sayNum = function () { console.log(this.num); };Copy the code

Advantages:

  1. The SuperType constructor is called only once, avoiding creating unnecessary properties on subtype. prototype.

  2. Can use Instanceof and isPrototypeOf() normally.

Disadvantages:

  1. Implementation is complicated

6. ES6 class inheritance

The class keyword is introduced in ES6. The class extends extends extends, and static methods of a class are defined using the static keyword. This is much cleaner and more convenient than ES5’s inheritance by modifying the stereotype chain. Note that the class keyword is just syntactic sugar for the stereotype, and JavaScript inheritance is still implemented based on the stereotype.

class Pet { constructor(name, age) { this.name = name; this.age = age; } showName() {console.log(" call method of parent class "); console.log(this.name, this.age); }} class Dog extends Pet {constructor(name, age, color) {super(name, age); // Call the parent constructor this.color = color through super; } showName() {console.log(" call subclass methods "); console.log(this.name, this.age, this.color); }}Copy the code

Advantages:

  1. Clear and convenient

Disadvantages:

  1. Not all browsers support class.

The resources

  1. JS implementation of several ways of inheritance
  2. Ruan Yifeng ES6 entry class inheritance
  3. JavaScript Advanced Programming
  4. JavaScript You Don’t Know