除了惯例的面对对象的思想,另外一种较流行的经过可复用组件建立类的方法是将简单的类混合到一块儿。你可能对这种混合的方式比较熟悉或对Scala语言的特性有理解,这种模式在JavaScript社区也有必定的人气。web
混合案例app
在下面的代码中,咱们展现了如何在TypeScript中混合模型,看完代码以后,再分析它的执行。函数
// Disposable Mixinclass Disposable { isDisposed: boolean; dispose() { this.isDisposed = true; } } // Activatable Mixinclass Activatable { isActive: boolean; activate() { this.isActive = true; } deactivate() { this.isActive = false; } } class SmartObject implements Disposable, Activatable { constructor() { setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500); } interact() { this.activate(); } // Disposable isDisposed: boolean = false; dispose: () => void; // Activatable isActive: boolean = false; activate: () => void; deactivate: () => void; } applyMixins(SmartObject, [Disposable, Activatable]) var smartObj = new SmartObject(); setTimeout(() => smartObj.interact(), 1000); ////////////////////////////////////////// 在你代码的某处////////////////////////////////////////function applyMixins(derivedCtor: any, baseCtors: any[]) { baseCtors.forEach(baseCtor => { Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { derivedCtor.prototype[name] = baseCtor.prototype[name]; }) }); }
理解案例this
该代码例子刚开始的两个类是将被做为混合部分的类。你能够看到,每一类都有特定的功能。以后咱们将这两个类混合成一个同时拥有这两个类的功能的新类。spa
// Disposable Mixinclass Disposable { isDisposed: boolean; dispose() { this.isDisposed = true; } } // Activatable Mixinclass Activatable { isActive: boolean; activate() { this.isActive = true; } deactivate() { this.isActive = false; } }
接下来,咱们建立一个新的类,并将这两个类混合到这个新的类中。详细的看看它是如何作的:prototype
class SmartObject implements Disposable, Activatable {
你可能会注意到的第一件事是咱们使用了"implements",而不是"extends"。这样作是将类做为接口对待,只使用了"Disposable"和"Activatable"后面的类型,而不是实现这两个接口。这也意味着咱们须要在类中实现这两个接口,但这偏偏是咱们想经过混合来避免的问题。code
为了知足这些需求,咱们为这些将要混合进来的属性建立占位符和其类型。这样可让编译器认识到这些成员在运行时是可用的。这么作能达到混合的利益,即便咱们须要提早编写成员的占位符及其类型。orm
// DisposableisDisposed: boolean = false; dispose: () => void;// ActivatableisActive: boolean = false; activate: () => void; deactivate: () => void;
最后,咱们将这两个类混合进新的类,建立全部的实现方式。对象
applyMixins(SmartObject, [Disposable, Activatable])
最后,咱们建立一个帮助咱们作混合的辅助函数。这个函数遍历每一个混合类上的每一个属性,而且将他们拷贝到混合后的类中,填充在以前所留的占位符而且将其实现。接口
function applyMixins(derivedCtor: any, baseCtors: any[]) { baseCtors.forEach(baseCtor => { Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => { derivedCtor.prototype[name] = baseCtor.prototype[name]; }) }); }