This is the 12th day of my participation in the August Text Challenge.More challenges in August

preface

Now that we’ve covered six inheritance methods in javascript, all of which are based on ES5, we’ll take a look at a new one in ES6: class inheritance

class

In ES6, the concept of classes was introduced as templates for objects. A class is an abstraction of a class of things that have the same characteristics in real life. Class is a reference data type similar to byte, short, int, long, float, double and other basic data types, but the difference is that it is a complex data type. Because it is essentially a data type, not concrete data, it does not exist in memory, cannot be manipulated directly, and becomes operable only when it is instantiated as an object.

Classes are defined in JavaScript using the class keyword. Basically, classes in ES6 can be seen as syntactic sugar, and most of its functions can be done in ES5. The new class writing method simply makes the writing of object prototypes clearer, more like the syntax of object-oriented programming. Let’s look at a piece of code:

class Point{
    constructor(x, y){
        this.x = x;
        this.y = y;
    }

    toString(){
        return `(${this.x},${this.y})`
    }
}
Copy the code

The above code defines a class that has a constructor method, which is the constructor, and the this keyword represents the instance object of the class. That is, the constructors in ES5 correspond to the constructors in ES6.

The class defines a toString method in addition to the constructor. When you define a class’s methods, you don’t need to use the function keyword. In addition, the methods do not need to be separated by commas, otherwise an error will be reported. The new keyword is instantiated directly, as is the case with constructors in ES5.

The constructor method

The constructor method is the default method of a class, which is automatically called when an instance of an object is created using the new keyword. A class must have a Constructor method, and an empty default constructor method is automatically added if no definition is displayed.

As in ES5, instance attributes are defined on the stereotype (class) unless the display is defined on its own (this object). Look at the following code:

class Point{ constructor(x, y){ this.x = x; this.y = y; } the toString () {return ` (${this. X}, ${this. Y}) `}} var p = new Point (2, 3); p.toString(); / / (2, 3) p.h asOwnProperty (' x '); //true p.hasOwnProperty('y'); //true p.hasOwnProperty('toString'); //false p.__proto__.hasOwnProperty('toString') //trueCopy the code

In the above code, x and y are both properties of the instance object P (defined on this), so hasOwnProperty returns true, while toString is a property of the prototype object (defined on Point), so hasOwnProperty returns false. These are consistent with es5 behavior.

All instances of the class share a stereotype object

Var p1 = Point (1, 2); Var p2 = Point (2, 3); p1.__proto__ === p2.__proto__; ///trueCopy the code

Class inheritance

Class inheritance is implemented through the extends keyword and the supper method calls the parent constructor, which is much cleaner and more convenient than es5’s implementation of inheritance by modifying the prototype chain.

class ColorPoint extends Point{}
Copy the code

The above code simply implements class inheritance. It defines a ColorPointer class that extends from Point using the extends keyword. ColorPoint inherits all the properties and methods of Point, but since ColorPoint has no code inside, So now the two classes are exactly the same, which is a copy of the Point class. Let’s add some code:

Class ColorPoint extends Point{constructor(x,y,color){constructor(x,y,color){constructor(x,y,color); //ColorPoint new attribute color} toString(){return this.color + "+ super.tostring (); ToString ()}}Copy the code

In the code above, the super keyword appears in both the constructor and toString methods, where it represents the parent’s constructor, which is used to create a new parent’s this object.

  1. Subclasses must call the super method from the constructor method or they will get an error when creating a new instance. This is because the subclass doesn’t have its own This object. Instead, it inherits the parent’s this object and processes it. If you don’t call super, the subclass doesn’t get this.
  2. If the subclass does not show the add Constructor method, this method is added by default. That is, any subclass has a constructor method regardless of whether the definition is displayed
  3. In the constructor of a subclass, you can use this keyword only after super is called. Otherwise, an error will be reported. This is because the subclass instance is built based on processing the superclass instance, and only super can return the superclass instance.

Class’s ProshtoType and __proto__ attributes

In most browsers’ ES5 implementations, each object has a __proto__ attribute that points to the prototype attribute of the corresponding constructor. Class is the syntactic sugar of the constructor and has both the Prototype and __proto__ attributes, so there are two inheritance chains

  1. The __proto__ attribute of a subclass, which indicates constructor inheritance, always points to the parent class
  2. The __proto__ attribute of the protoclass’s prototype attribute, which indicates method inheritance, always points to the prototype attribute of the parent class
class A{}

class B extends A{}

B.__proto__ === A //true
B.prototype.__proto__ === A.prototype //true
Copy the code

In the code above, the __proto__ attribute of subclass B executes parent A, and the __proto__ attribute of subclass B’s Prototype attribute points to parent A’s Prototype attribute. The result is that class inheritance is implemented according to the following pattern:

Class A{} class B{} // an instance of B inherits an instance of object.setProtoTypeof (b.prototype, a.prototype); Object.setprototypeof (B, A);Copy the code

The object. setPrototypeOf method is implemented in the following mode:

Object.setPrototypeOf = function(obj, proto){
    obj.__proto__ = proto;
    return obj;
}
Copy the code

This results in the code above:

Object.setprototypeof (b.prototype, a.prototype) // equivalent to b.prototype.__proto__ = a.prototype object.setprototypeof (B, A) // equivalent to b. __proto__ = A;Copy the code

As an object, the __proto__ attribute of subclass B is the parent class A; As a constructor, the prototype property of subclass B is an instance of the parent class.

That’s all about class inheritance in ES6. This concludes the seven inheritance methods in JavaScript.