JavaScript Advanced Programming Inheritance

1. Abstract Base Class

Sometimes it may be necessary to define a class that can be inherited by other classes but not instantiated itself. Although ECMAScript does not
There is a syntax that specifically supports this class, but it is also easy to implement through new.target. New.target saved with new keyword keys
Class or function used. Instantiation of abstract base classes can be prevented by detecting whether new.target is an abstract base class when instantiating:

Abstract Base Class

class Vehicle {  
 constructor() {  
 console.log(new.target);  
 if (new.target === Vehicle) {  
 throw new Error('Vehicle cannot be directly instantiated'); 
class Bus extends Vehicle {}  
new Bus(); // class Bus {}  
new Vehicle(); // class Vehicle {}  
// Error: Vehicle cannot be directly instantiated  

In addition, by checking in the abstract base class constructor, you can require that a derived class must define a method. Because the prototype method is
Class constructors already exist before they are called, so the this keyword can be used to check the appropriate method:
Abstract Base Class

class Vehicle {  
 constructor() {  
 if (new.target === Vehicle) {  
 throw new Error('Vehicle cannot be directly instantiated');  
 }  
 if (!this.foo) {  
 throw new Error('Inheriting class must define foo()');  
 }  
 console.log('success!');  
 }  
}  

Derived Class

class Bus extends Vehicle {  
 foo() {}  
}  

Derived Class

class Van extends Vehicle {}  
new Bus(); // success!  
new Van(); // Error: Inheriting class must define foo() 

2. Inherit built-in types

The ES6 class provides a smooth mechanism for inheriting built-in reference types, which developers can easily extend:

  shuffle algorithm 
  class SuperArray extends Array {  
 shuffle() {  
 for (let i = this.length - 1; i > 0; i--) {  
 const j = Math.floor(Math.random() * (i + 1));  
 [this[i], this[j]] = [this[j], this[i]]; 
 }  
 }  
}  
let a = new SuperArray(1, 2, 3, 4, 5);  
console.log(a instanceof Array); // true  
console.log(a instanceof SuperArray); // true 8.4 class 263  
console.log(a); // [1, 2, 3, 4, 5]  
a.shuffle();  
console.log(a); // [3, 1, 4, 5, 2]  

Some methods of built-in types return new instances. By default, the type of returned instance is the same as that of the original instance:

class SuperArray extends Array {}  
let a1 = new SuperArray(1, 2, 3, 4, 5);  
let a2 = a1.filter(x => !!(x%2))  
console.log(a1); // [1, 2, 3, 4, 5]  
console.log(a2); // [1, 3, 5]  
console.log(a1 instanceof SuperArray); // true  
console.log(a2 instanceof SuperArray); // true  

If you want to override this default behavior, you can override the Symbol.species accessor, which decides to return the
Classes used in the instance:

class SuperArray extends Array {  

 **static get [Symbol.species]() {**  

 **return Array;**  

 **}**  

}  
let a1 = new SuperArray(1, 2, 3, 4, 5);  
let a2 = a1.filter(x => !!(x%2))  
console.log(a1); // [1, 2, 3, 4, 5]  
console.log(a2); // [1, 3, 5]  
console.log(a1 instanceof SuperArray); // true  
**console.log(a2 instanceof SuperArray); // false**

3. Class Mixing

Aggregating the behavior of different classes into one class is a common JavaScript pattern. Although ES6 does not explicitly support multiple inheritance, it does
This behavior can be easily simulated with existing features.
Note that the Object.assign() method is designed to blend in object behavior. Only behavior that requires mixing classes
Then it is necessary to implement the mixed expression yourself. If you just need to mix attributes of multiple objects, use
Object.assign() is OK.
In the code snippet below, the extends keyword is followed by a JavaScript expression. Any that can be parsed into a class or
The expressions for each constructor are valid. This expression is evaluated when evaluating the class definition:

class Vehicle {}  
function getParentClass() {  
 console.log('evaluated expression');  
 return Vehicle;  
 class Bus extends **getParentClass()** {}  
}  

Evaluable expression

Mixing patterns can be achieved by concatenating multiple mixed elements in an expression that eventually resolves to an expression that can be
Inherited class. If the Person class needs to combine A, B, C, then it needs some mechanism to implement B inherit A, C inherit B, and
Then inherit C to combine A, B, and C into this superclass. There are different strategies for implementing this pattern.
A strategy is to define a set of "nestable" functions, each receiving a superclass as a parameter, and a mixed class as
Subclass of this parameter and returns this class. These combinatorial functions can be called concatenatively and ultimately combined into superclass expressions:

class Vehicle {}  
let FooMixin = (Superclass) => class extends Superclass {  
 foo() {  
 console.log('foo');  
 }  
};  
let BarMixin = (Superclass) => class extends Superclass {  
 bar() {  
 console.log('bar');  
 }  
};  
let BazMixin = (Superclass) => class extends Superclass {  
 baz() {  
 console.log('baz');  
 }  
};  
class Bus extends FooMixin(BarMixin(BazMixin(Vehicle))) {}  
let b = new Bus();  
b.foo(); // foo  
b.bar(); // bar  
b.baz(); // baz  

Nested calls can be expanded by writing an auxiliary function:

class Vehicle {}  
let FooMixin = (Superclass) => class extends Superclass {  
 foo() {  
 console.log('foo');  
 }  
};  
let BarMixin = (Superclass) => class extends Superclass {  
 bar() {  
 console.log('bar');  
 }  
};  

let BazMixin = (Superclass) => class extends Superclass {  
 baz() {  
 console.log('baz');  
 }  
};  

**function mix(BaseClass, ...Mixins) {**  
 **return Mixins.reduce((accumulator, current) => current(accumulator), BaseClass);**  
**}**  

**class Bus extends mix(Vehicle, FooMixin, BarMixin, BazMixin) {}**  
let b = new Bus();  
b.foo(); // foo  
b.bar(); // bar  
b.baz(); // baz

Note that many JavaScript frameworks, especially React, have abandoned the mixed mode and moved to the combined mode (putting methods in place)

Extract into separate classes and auxiliary objects and combine them without inheritance). This reflects the crowd

Well-known software design principle: "composition over inheritance". This design principle is

Many people follow and offer great flexibility in code design

summary

That's what it is today JavaScript Advanced Programming (2) Inheritance
 Will keep updating...
Originality is not easy. We look forward to your comments and comments😜😜

Tags: Javascript ECMAScript

Posted on Tue, 30 Nov 2021 15:12:37 -0500 by KresentPhresh