This is the 15th day of my participation in the August More Text Challenge

Inheritance in JS

In object oriented, we mainly study the following problems :(the relationship between classes and instances)

  • Inheriting subclasses inherit from their parent class
  • Encapsulation adds methods to instances and methods to prototypes
  • Polymorphism (overwrite, overload)

Inheritance: Two classes A and B. For instances of class B to use the attributes and methods of class A, we need class B to inherit from class A. We call class B subclasses and class A superclasses.

function Super() {}function A() {}

A.prototype.say = function () {
   console.log('hello World');
};

let b = newB(); B is an instance of class B that wants to use the properties and methods of class Aconsole.log(b.say);  undefinedWhy isundefined? Object. Attribute name first to see whether they have private attributes, if not, to the instance of the class's prototype to find public attributes and methods, if there is no prototype, according to the prototype object __proto__ always findObjectTo the prototype of the base class, if not already returnedundefined; Now we need b to use class A say method, now we need to inherit;Copy the code

Second, prototype chain inheritance

JavaScript is object-oriented through prototype objects, so the first way of inheritance is prototype chain inheritance. The core of this method is to extend the prototype chain of a subclass, by which the subclass instance can access the attributes and methods of the parent class in the process of searching the prototype chain

  • Stereotype inheritance: Rewriting A stereotype object of subclass B to an instance of its parent class A.

B.prototype = new A(); Make common and private attributes of the parent class public attributes of the child class


function A() {
}
A.prototype.age = 19;
A.prototype.say = function () {
   console.log('Say method from Class A prototype')};function B() {}

B.prototype = newA(); Rewrite A class B prototype into an instance of class A;let b = new B();

console.log(b);
console.log(b.__proto__);  {text: 'xxx', __proto__.... }console.log(b.age);
console.log(b.say);
Copy the code

Change the prototype of B into an instance of class A, then access the age property of B through B. Age, first search in the private property, there is no age property, then search on the prototype of the class B belongs to (B.prototype), at this time the prototype object is the instance object of A, there is no age property in the prototype object. The prototype object __proto__ has the age attribute on a. prototype. The prototype of A has the age attribute

  • Stereotype inheritance is the process of making both public and private properties of subclasses private properties;
  • Disadvantages: Overwriting the prototypeobject of a subclass causes the constructor property on the prototypeobject of the subclass to be overwritten and needs to specify the inherited constructor.

Borrow constructor inheritance

Inheritance means that instances of a subclass can access attributes of their parent class in some way, so adding attributes of the parent class directly to instances of a subclass is naturally a viable inheritance method.

Borrow constructors: Treat the parent class as a normal function, and call executes the parent function in the child’s function body.

function A() {
   this.a = 'aa';
   this.say = function () {
      console.log('A say');
   }
}
A.prototype.public = 'public';

function B() {
   A.call(this);  thisIs an instance of class B, a.call (thisPut A inthisShould be an instance of B (in the constructor of B)thisIs an instance of B) and so passes in AthisAll attributes added by.xxx = XXX are added to instances of B. }let b = new B();
console.log(b);  {a: 'aa'.say: fun..... }let b2 = new B();
console.log(b2.say === b.say);  false;

Copy the code

Borrow constructor inheritance:

  • Call a.call (this); call a.call (this); call a.call (this);
  • The call method is used to modify the reference to this, thus changing this from A to an instance of B; The attributes added in function A via this. XXX = XXX are added to instances of B;
  • Features: Only the private attributes and methods of the parent class can be inherited into the private attributes and methods of the subclass.

4. Combinatorial inheritance

After experiencing the first two inheritance methods, we find that they have their own advantages and disadvantages. If we can make proper use of the advantages of both, we can avoid their respective disadvantages, which gives birth to the combination inheritance method.

Composite inheritance: stereotype chain inheritance + borrowed constructor inheritance

  • Stereotype chain inheritance: inheriting private and common parent classes to public child classes;
  • Borrow constructor inheritance: Inherits from a parent class private to a subclass private
function A() {
   this.a = 'private'
}
A.prototype.text = 'the public';
A.prototype.say = function () {
   console.log('A public say method ')};function B() {
   A.call(this); Borrow constructor inheritance, inherit parent class private} b.prototype =newA(); Stereotype chain inheritance inherits private and public attributes of the parent class; B.prototype.constructor = B;let b = new B();
console.log(b.text); publicconsole.log(b.a); privateCopy the code
  • Composite inheritance is not without its drawbacks. Composite inheritance makes the parent’s private inheritance twice, one private when borrowed from constructor inheritance and the other public when borrowed from stereotype inheritance.

Five, the original type inheritance

Prototype inheritance can be thought of as a “bridge” that inserts a link in the prototype chain lookup process.

Primitive inheritance: inherit the public attributes of the parent class to the public attributes of the child class;

Create a new object with its __proto__ pointing to A.prototype, and use the new object as the prototype of class B;

  • Create an object with its __proto__ pointing to obj
 Object.create(obj)

Copy the code
  • Examples of primitive type inheritance
function A() {
   this.private = 'private private';
}
A.prototype.public = 'public public';

function B() {}

B.prototype = Object.create(A.prototype); Create an object whose __proto__ points to a.prototype b.prototype. constructor = B;let b = new B();
console.log(b.public);
Copy the code

Note that the original type inheritance also changes the orientation of class B archetypes, so you need to respecify the constructor!

Parasitic combinatorial inheritance

Parasitic combinatorial inheritance: primitive inheritance + borrowed constructor inheritance

  • Primitive inheritance: Inherits from a parent class that is public to a subclass instance that is public
  • Borrowed constructor inheritance: Inherits attributes that are private to the parent class
function A() {
   this.private = 'Private property';
}

A.prototype.public = 'Public property';

function B() {
   A.call(this); Borrow constructor inheritancethis.name = 'B private';
}

 
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

let b = new B();  {name: 'private'.private: 'Private property'}
console.log(b.private); Inherited private propertiesconsole.log(b.public); Public property inherited fromCopy the code

Seven, impersonating object inheritance

Object inheritance: generate an instance of the parent class in the constructor of the child class, iterate over the instance of the parent class, add attributes to the instance of the child class;

function A() {
   this.private = 'Private property';
}
A.prototype.public = 'Public property';

function B() {
   this.name = 'B private property ';
   let tmp = new A();
   for (let key in tmp) {
      this[key] = tmp[key]; }}let b = new B();
console.log(b);
Copy the code

Classes and inheritance in ES6

8.1 Classes in ES6 and ES5

  • ES5 A function is a class

  • ES6 uses the backend language to create a class by adding the class keyword

  • ES5

function Teacher(name, age, subject) {
   this.name = name;
   this.age = age;
   this.subject = subject;
}
Teacher.motor = 'Impart knowledge and enlighten doubts';
Teacher.prototype.teach = function () {
   console.log(this.name + this.age);
};

let t = new Teacher('qq'.19.'js');
Copy the code
  • ES6

class Teacher {
   constructor (name, age, subject) {This inside passesthis.xxx = XXX adds private attributes to the instancethis.name = name;
      this.age = age;
      this.subject = subject; } add public teach () {console.log(this.name + this.age + this.subject); } add static methodsstatic motor = 'Impart knowledge and enlighten doubts';
   static getMotor () {
      console.log('We are U'); }}let t = new Teacher('qq'.18.'JS');
t.teach();
console.log(Teacher.motor);
Teacher.getMotor();
Copy the code

8.2 ES6 inheritance

ES6 inheritance: extends keyword

class A {
   constructor (name, age) {
      this.name = name;
      this.age = age; } Public method (added to prototype) say () {console.log(`The ${this.name} say`); }} ES6 inheritanceextendsKeyword implementation inheritanceclass B extends A {B inherits class Aconstructor (x, y, forName, forAge) {Note: in use of ES6extendsKeyword must be used beforesuper(a);superRepresents a constructor for the parent classsuper(forName, forAge); Note:this.x = x;
      this.y = y; }}let b = new B('x'.'y'.'qq'.18);
console.log(b);
b.say();
Copy the code
  • The inheritance principle of ES6 is parasitic combinatorial inheritance