Inheritance is most discussed in object-oriented programming. Most object-oriented languages support two kinds of inheritance, one is interface inheritance and the other is implementation inheritance. The former inherits only method signatures (such as abstract classes that inherit interfaces in Java), while the latter inherits actual methods. Interface inheritance does not exist in ECMAScript. Implementing inheritance is the only way ECMAScript can be inherited, and this is mostly done through a chain of stereotypes. (When we talk about inheritance in ECMAScript, we don’t really mean inheritance, class means copy. But classes in JS are shared. We’re just mimicking a real class. So the class in JS is basically just a syntactic sugar for the existing [[prototype]] mechanism!

If you are not aware of the various ES5 inheritances, I recommend you read this article and come back later.

Parasitic combinatorial inheritance

In ES5, there are stereotype chain inheritance, embeded constructor inheritance, primitive inheritance, parasitic inheritance, and parasitic combinatorial inheritance. Parasitic combination inheritance is undoubtedly the most perfect inheritance mode. (actually is the prototype sharing) in JS all inheritance is the prototype sharing, so its prototype sharing is what a relationship?

Here is our sample code to see if you have the inheritance diagram in mind:

function implementInheritance(fFunc, sFunc) { const prototype = Object(fFunc.prototype); Constructor = sFunc; prototype.constructor = sFunc; prototype.constructor = sFunc; prototype.constructor = sFunc; SFunc. Prototype = prototype; } function Father(identity) {this.identity = identity; Enclosing sayFather = function () {the console. The log (' I am a Father ')}} Father. The prototype. SayFatherIdentity = function () { console.log("Father -> sayFatherIdentity -> this.identity", this.identity) } function Son(fIdentity, selfIdentity) { Father.call(this, fIdentity); this.selfIdentity = selfIdentity; SaySon = function () {console.log(' I am Son')}} implementInheritance(Father, Son); Son.prototype.saySonIdentity = function () { console.log("Son -> saySonIdentity -> this.selfIdentity", This. selfIdentity)} const newF = new Father(' Father '); Const newS = new Son(' parent --s',' child ');Copy the code

After reading the code, does the diagram of the prototype come to mind? If not, take a look at the picture below:

Reading:

After using the implementInheritance() function, when we add methods to the prototype object, we also add methods to the prototype of the parent constructor because we have created an object that has the same reference as the parent constructor. SFunc. Prototype = prototype; So the child constructor’s prototype is also the parent constructor’s prototype. Constructor = sFunc; constructor = sFunc; constructor = sFunc; This code changes the direction of the parent constructor’s constructor property. After instantiating Father, we see that the constructor actually points to the Son constructor. This is the shared structure of the prototype of parasitic combinatorial inheritance.

class extends

ES6 inheritance is really just syntactic sugar from ES5 inheritance (class inheritance still uses the concepts of stereotypes and constructors, and is based on stereotype sharing), but its prototype sharing diagram is nothing like that of ES5.

Take a look at the following sample code:

// Father class constructor(identity) {this.identity = identity} sayFatherIdentity() {console.log("Father ") -> sayFatherIdentity -> this.identity", This.identity)} sayFather = () => {console.log(' I am Father')}} constructor(fatherIdentity, selfIdentity) { super(fatherIdentity) this.sonIdentity = selfIdentity } saySonIdentity() { console.log("Son -> saySonIdentity -> this.sonIdentity", This.sonidentity)} saySon = () => {console.log(' I am Son')}} const newF = new Father(' Father '); Const newS = new Son(' parent ', 'child ');Copy the code

See the prototype sharing diagram below:

Reading:

We can see that the child constructor has its own prototype object, but the __proto__ of the child refers to the parent constructor’s prototype object. It is nice that both the child and the parent class have their own constructors. The prototype __proto__ of a subclass refers to the prototype object of the parent class. For both instantiated objects, the __proto__ === parent of the child instantiated object’s prototype object.

The difference between

Both parasitic composite inheritance and class inheritance are implemented based on shared archetypal objects.

  1. For the sharing of stereotype objects, the stereotype sharing of parasitic composite inheritance is based directly on the parent constructor. In class inheritance, each class has its own prototype object, which is linked and shared based on the prototype chain.

  2. The main difference with constructors is that class constructors must be called using the new operator. A normal constructor that does not call new takes the global this as its internal object.

Past wonderful

  • The front end Leader asked me to talk to my colleagues about the event loop

  • React compares the status update mechanism with Vue

  • Do you React to a tree shuttle box?

  • 10 Mistakes to avoid when Using React

  • Webpack Packaging Optimization Direction Guide (Theory)

  • What if VUE encounters drag-and-drop dynamically generated components?

  • JS Coding tips, most people can’t!!

  • TypeScript doesn’t it smell good? Come on!