Mixins

介绍

混入示例

下面的代码演示了如何在TypeScript里使用混入。 后面我们还会解释这段代码是怎么工作的。

理解这个例子

代码里首先定义了两个类,它们将做为mixins。 可以看到每个类都只定义了一个特定的行为或功能。 稍后我们使用它们来创建一个新类,同时具有这两种功能。

  1. class Disposable {
  2. isDisposed: boolean;
  3. dispose() {
  4. this.isDisposed = true;
  5. }
  6. }
  7. // Activatable Mixin
  8. class Activatable {
  9. isActive: boolean;
  10. this.isActive = true;
  11. }
  12. deactivate() {
  13. this.isActive = false;
  14. }
  15. }

首先应该注意到的是,没使用extends而是使用implements。 把类当成了接口,仅使用Disposable和Activatable的类型而非其实现。 这意味着我们需要在类里面实现接口。 但是这是我们在用mixin时想避免的。

我们可以这么做来达到目的,为将要mixin进来的属性方法创建出占位属性。 这告诉编译器这些成员在运行时是可用的。 这样就能使用mixin带来的便利,虽说需要提前定义一些占位属性。

  1. // Disposable
  2. dispose: () => void;
  3. isActive: boolean = false;
  4. activate: () => void;
  5. deactivate: () => void;

最后,创建这个帮助函数,帮我们做混入操作。 它会遍历mixins上的所有属性,并复制到目标上去,把之前的占位属性替换成真正的实现代码。

  1. function applyMixins(derivedCtor: any, baseCtors: any[]) {
  2. baseCtors.forEach(baseCtor => {
  3. Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
  4. derivedCtor.prototype[name] = baseCtor.prototype[name];
  5. })
  6. });