TypeScript Mixins

概念

Mixins 是一种软件设计模式,在 JavaScript 中用于实现代码复用和组合功能。它允许将多个不同的行为或特性组合到一个类中,而无需使用传统的类继承。通过 Mixins,可以从多个源获取功能,使代码更加灵活和可维护。

与传统面向对象继承的区别

  • 传统继承
    • 通常是单一的层次结构,一个类只能从一个父类继承。
    • 继承关系较为严格,可能导致复杂的类层次结构和较高的耦合度。
  • Mixins
    • 可以从多个不同的源组合功能,更加灵活。
    • 不是基于严格的父子关系,而是通过合并代码来实现功能共享。

示例

定义两个混入类:

// Disposable Mixin
class Disposable {
  isDisposed: boolean = false;
  dispose() {
    this.isDisposed = true;
  }

}

// Activatable Mixin
class Activatable {
  isActive: boolean = false;
  activate() {
    this.isActive = true;
  }
  deactivate() {
    this.isActive = false;
  }
}

定义主类 SmartObject

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;
}

注意:这里使用的是 implements 关键字,而不是extends

  • SmartObject的目的是:组合 DisposableActivatable 的功能。
  • 通过 implements 关键字声明实现这两个 Mixins,表明它应该具有这两个 Mixins 中的所有属性和方法。
    把类当成了接口,仅使用DisposableActivatable的类型而非其实现。 这意味着需要在类里面实现接口。 但是这是在用mixin时想避免的。
  • 对于 DisposableActivatable 中的属性和方法,进行了类型声明,但没有具体实现。
    这是为将要mixin进来的属性方法创建出占位属性。

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

function applyMixins(derivedCtor: any, baseCtors: any[]) {
  baseCtors.forEach(baseCtor => {
    Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
      derivedCtor.prototype[name] = baseCtor.prototype[name];
    });
  });
}
  • 这是一个通用的 Mixins 应用函数。
  • 接受两个参数,derivedCtor 表示要应用 Mixins 的派生类构造函数(这里是 SmartObject),baseCtors 是一个包含要混入的基类构造函数的数组(这里是 [Disposable, Activatable])。
  • 遍历 baseCtors 数组中的每个基类构造函数:
    • 通过 Object.getOwnPropertyNames(baseCtor.prototype) 获取基类原型上的所有自有属性名。
    • 对于每个属性名,将基类原型上的对应属性赋值给派生类的原型,从而实现了将 Mixins 的功能添加到派生类上。

最后,把mixins混入定义的类,完成全部实现部分。

applyMixins(SmartObject, [Disposable, Activatable]);

// 创建 SmartObject 的实例 smartObj
let smartObj = new SmartObject();
setTimeout(() => smartObj.interact(), 1000);
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值