Copyright
Article reprinted from: HTTPS://GITHUB.COM/ZHONGSP
It is recommended that you jump directly to the URL above to see the latest version.
Introduced
In addition to the traditional approach to object-oriented inheritance, one way to create classes from reusable components is to federate the code of another simple class. You may be familiar with Mixins and its features in languages like Scala, but it's also popular in JavaScript.
Mixed sample
The following code shows how to use mixed in typescript. We'll also explain how this code works in the back.
Disposable MixinClass Disposable {isdisposed:Boolean Dispose () {this.isdisposed =True }}Activatable MixinClass Activatable {isActive:Boolean Activate () {This.isactive =True } deactivate () {This.isactive =False }}Class SmartObjectImplements disposable, Activatable {Constructor () {setinterval () =Console.log (This.isactive +" : " +this.isdisposed),500); } interact () {This.activate (); }Disposable isdisposed:Boolean =False Dispose: () =voidActivatable isActive:Boolean =False Activate: () =void Deactivate: () =Void;} Applymixins (SmartObject, [disposable, Activatable])var smartobj = new SmartObject (); SetTimeout (() = Smartobj.interact (), 1000); //////////////////////////////////////////in your runtime library somewhere/////////////////////////// function applymixins (derivedctor: Any , basectors: any[]) {Basectors.foreach ( Basector = { object.getownpropertynames (basector.prototype). ForEach (name = = {Derivedctor.prototype[name ] = Basector.prototype[name]; }) });}
Understand This example
The code first defines two classes, which are mixins. You can see that each class defines only one specific behavior or function. We'll use them later to create a new class with both of these features.
// Disposable Mixinclass Disposable { isDisposed: boolean; dispose() { this.isDisposed = true; }}// Activatable Mixinclass Activatable { isActive: boolean; activate() { this.isActive = true; } deactivate() { this.isActive = false; }}
The following creates a class that combines the two mixins. Let's take a look at how this is done:
class SmartObject implements Disposable, Activatable {
The first thing to notice is that it's not used extends
implements
. Classes are treated as interfaces, using only the types of disposable and activatable rather than their implementations. This means that we need to implement the interface within the class. But this is what we want to avoid when we use mixin.
We can do this to achieve the goal of creating a placeholder attribute for the property method that will be mixin in. This tells the compiler that these members are available at run time. This makes it possible to use the convenience of mixin, although some placeholder attributes need to be defined in advance.
// DisposableisDisposed: boolean = false;dispose: () => void;// ActivatableisActive: boolean = false;activate: () => void;deactivate: () => void;
Finally, the mixins is mixed into the defined class to complete the implementation part.
applyMixins(SmartObject, [Disposable, Activatable])
Finally, create this helper function to help us do the mixing. It iterates through all the attributes on the mixins and copies them to the target, replacing the previous placeholder property with the real implementation code.
function applyMixins(derivedCtor: any, baseCtors: any[]) { baseCtors.forEach(baseCtor => { Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { derivedCtor.prototype[name] = baseCtor.prototype[name]; }) });}
Reprint: "TypeScript Chinese Introductory Course" 10, mixed