在这篇文章中,将用简单清晰的术语向你介绍 TypeScript 中的 mixins 概念,即使你是新手。
在 TypeScript 中拓展类
就像许多面向对象的编程语言一样,TypeScript 也有类。类是创建对象的蓝图——它们基本上用于封装对象中的数据。TypeScript 类可以这样定义:
class Subscribe {
Remind() {
console.log("Remember to subscribe to my channel");
}
}
该类包含一个名为 remind 的函数,该函数在 DOM 的控制台中记录字符串。如果你有一个新的命名为 Youtube 的类
class Youtube {
Begin() {
console.log("Hi, Welcome to my channel!");
}
Ending() {
console.log("Thank you for watching my video!");
}
}
如果你想有一个类来扩展我们已经定义的两个类,以便在这个新类中访问它们,TypeScript 不允许这样做,所以它被标记为错误。你可以这样试试:
export class Recording extends Youtube, Subscribe{}
如果你尝试过这样做,你会看到当你把鼠标悬停在 IDE 上时,会告诉你 TypeScript 类只能扩展一个类的模糊行。当您第一次遇到这个问题时,您可能会想起 interfaces。
interfaces
在 TypeScript 中,类只能继承一个类,但接口可以继承多个类。使用 TypeScript 接口来解决我们的问题:
export class Recording {}
export interface Recording extends Youtube, Subscribe {}
const recording = new Recording();
recording.Remind();
recording.Ending();
我们创建一个接口,然后尝试查看是否可以访问已经定义的两个类中的函数。如果你在终端上运行 build:
tsc filename.ts
node filename.js
您将在构建的终端中看到一个错误,说明提醒和结束不是函数。这是因为 TypeScript 接口虽然可以扩展类,但却没有类的实现。这让我们回到了最初的问题,即在 TypeScript 的一个新类中不能访问多个类。
解决方案: Mixins
Mixins是一种在面向对象编程范式中实现重用组件的方法。对于我们前面的问题,可以是用一个mixins的辅助函数来解决,也就是在TypeScript的一个新类中扩展两个类。所以如果你是一个前端开发人员并使用SASS,你可能对mixins很熟悉。这是相同的概念,但用于扩展类。这个helper函数可以在TypeScript的官方文档中找到。
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach((baseCtor) => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach((name) => {
Object.defineProperty(
derivedCtor.prototype,
name,
Object.getOwnPropertyDescriptor(baseCtor.prototype, name)
);
});
});
}
现在你可以使用ApplyMixins函数来构建你的新类,像下面这样:
class Youtube {
Begin(){
console.log('Hi, Welcome to my channel!');
}
Ending(){
console.log('Thank you for watching my video!');
}
}
class Subscribe {
Remind(){
console.log('Remember to subscribe to my channel');
}
}
// export class Recording extends Youtube, Subscribe{}
function applyMixins(derivedCtor: any, baseCtors: any[]) {
baseCtors.forEach(baseCtor => {
Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
});
});
}
export class Recording {}
export interface Recording extends Youtube, Subscribe{}
applyMixins(Recording,[Youtube, Subscribe]);
const recording = new Recording
recording.Remind();
recording.Ending();
总结
本文简单介绍了TypeScript的Mixins概念,以及如何使用它实现多类继承。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。