Typescript
  • Introduction
  • 快速上手
    • 5分钟了解TypeScript
    • ASP.NET Core
    • ASP.NET 4
    • Gulp
    • Knockout.js
    • React与webpack
    • React
    • Angular 2
    • 从JavaScript迁移到TypeScript
  • 手册
    • 基础类型
    • 变量声明
    • 接口
    • 类
    • 函数
    • 泛型
    • 枚举
    • 类型推论
    • 类型兼容性
    • 高级类型
    • Symbols
    • Iterators 和 Generators
    • 模块
    • 命名空间
    • 命名空间和模块
    • 模块解析
    • 声明合并
    • JSX
    • Decorators
    • 混入
    • 三斜线指令
    • JavaScript文件里的类型检查
    • 实用工具类型
  • 如何书写声明文件
    • 介绍
    • 库结构
    • 举例
    • 最佳实践
    • 深入
    • 模板
    • 发布
    • 使用
  • 工程配置
    • tsconfig.json
    • 工程引用
    • NPM包的类型
    • 编译选项
    • 配置 Watch
    • 在MSBuild里使用编译选项
    • 与其它构建工具整合
    • 使用TypeScript的每日构建版本
  • Wiki
    • TypeScript里的this
    • 编码规范
    • 常见编译错误
    • 支持TypeScript的编辑器
    • 结合ASP.NET v5使用TypeScript
    • 架构概述
    • 发展路线图
  • 新增功能
    • TypeScript 3.9
    • TypeScript 3.8
    • TypeScript 3.7
    • TypeScript 3.6
    • TypeScript 3.5
    • TypeScript 3.4
    • TypeScript 3.3
    • TypeScript 3.2
    • TypeScript 3.1
    • TypeScript 3.0
    • TypeScript 2.9
    • TypeScript 2.8
    • TypeScript 2.7
    • TypeScript 2.6
    • TypeScript 2.5
    • TypeScript 2.4
    • TypeScript 2.3
    • TypeScript 2.2
    • TypeScript 2.1
    • TypeScript 2.0
    • TypeScript 1.8
    • TypeScript 1.7
    • TypeScript 1.6
    • TypeScript 1.5
    • TypeScript 1.4
    • TypeScript 1.3
    • TypeScript 1.1
  • Breaking Changes
    • TypeScript 3.6
    • TypeScript 3.5
    • TypeScript 3.4
    • TypeScript 3.2
    • TypeScript 3.1
    • TypeScript 3.0
    • TypeScript 2.9
    • TypeScript 2.8
    • TypeScript 2.7
    • TypeScript 2.6
    • TypeScript 2.4
    • TypeScript 2.3
    • TypeScript 2.2
    • TypeScript 2.1
    • TypeScript 2.0
    • TypeScript 1.8
    • TypeScript 1.7
    • TypeScript 1.6
    • TypeScript 1.5
    • TypeScript 1.4
Powered by GitBook
On this page
  • Table of contents
  • 介绍
  • 混入示例
  • 理解示例

Was this helpful?

  1. 手册

混入

PreviousDecoratorsNext三斜线指令

Last updated 4 years ago

Was this helpful?

Table of contents

介绍

除了传统的面向对象继承方式,还流行一种通过可重用组件创建类的方式,就是联合另一个简单类的代码。 你可能在Scala等语言里对mixins及其特性已经很熟悉了,但它在JavaScript中也是很流行的。

混入示例

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

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

}

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

class SmartObject {
    constructor() {
        setInterval(() => console.log(this.isActive + " : " + this.isDisposed), 500);
    }

    interact() {
        this.activate();
    }
}

interface SmartObject extends Disposable, Activatable {}
applyMixins(SmartObject, [Disposable, Activatable]);

let 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 => {
            Object.defineProperty(derivedCtor.prototype, name, Object.getOwnPropertyDescriptor(baseCtor.prototype, name));
        });
    });
}

理解示例

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

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

}

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

下面创建一个类,结合了这两个mixins。 下面来看一下具体是怎么操作的:

class SmartObject {
    ...
}

interface SmartObject extends Disposable, Activatable {}

它将类视为接口,且只会混入Disposable和Activatable背后的类型到SmartObject类型里,不会混入实现。也就是说,我们要在类里面去实现。 这正是我们想要在混入时避免的行为。

最后,我们将混入融入到了类的实现中去。

// Disposable
isDisposed: boolean = false;
dispose: () => void;
// Activatable
isActive: boolean = false;
activate: () => void;
deactivate: () => void;

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

applyMixins(SmartObject, [Disposable, Activatable]);

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

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

首先注意到的是,我们没有在SmartObject类里面继承Disposable和Activatable,而是在SmartObject接口里面继承的。由于的存在,SmartObject接口会被混入到SmartObject类里面。

声明合并
介绍
混入示例
理解示例
↥ 回到顶端
↥ 回到顶端
↥ 回到顶端