转载:《TypeScript 中文入门教程》 10、混入

版权

文章转载自:https://github.com/zhongsp

建议您直接跳转到上面的网址查看最新版本。

介绍

除了传统的面向对象继承方式,还流行一种通过可重用组件创建类的方式,就是联合另一个简单类的代码。 你可能在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 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);

////////////////////////////////////////
// In your runtime library somewhere
////////////////////////////////////////

function applyMixins(derivedCtor: any, baseCtors: any[]) {
    baseCtors.forEach(baseCtor => {
        Object.getOwnPropertyNames(baseCtor.prototype).forEach(name => {
            derivedCtor.prototype[name] = 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 implements Disposable, Activatable {

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

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

// 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 => {
            derivedCtor.prototype[name] = baseCtor.prototype[name];
        })
    });
}
时间: 2024-11-05 14:23:10

转载:《TypeScript 中文入门教程》 10、混入的相关文章

转载:TypeScript 简介与《TypeScript 中文入门教程》

简介 TypeScript是一种由微软开发的自由和开源的编程语言.它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程.安德斯·海尔斯伯格,C#的首席架构师,已工作于TypeScript的开发. TypeScript扩展了 JavaScript 的句法,所以任何现有的JavaScript程序可以不加改变的在TypeScript下工作.TypeScript是为大型应用之开发而设计,而编译时它产生 JavaScript 以确保兼容性. TypeScrip

转载:《TypeScript 中文入门教程》 4、类

版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但这对于熟悉使用面向对象方式的程序员来说有些棘手,因为他们用的是基于类的继承并且对象是从类构建出来的. 从ECMAScript 2015,也就是ECMAScript 6,JavaScript程序将可以使用这种基于类的面向对象方法. 在TypeScript里,我们允许开发者现在就使用这些特性,并且编译后的J

转载:《TypeScript 中文入门教程》 9、泛型

版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性. 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能. 在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据. 这样用户就可以以自己的数据类型来使用组件. 泛型之Hello World 下面来创建第一个使用泛型的例

转载:《TypeScript 中文入门教程》 11、声明合并

版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 TypeScript有一些独特的概念,有的是因为我们需要描述JavaScript顶级对象的类型发生了哪些变化. 这其中之一叫做声明合并. 理解了这个概念,对于你使用TypeScript去操作现有的JavaScript来说是大有帮助的. 同时,也会有助于理解更多高级抽象的概念. 首先,在了解如何进行声明合并之前,让我们先看一下什么叫做声明合并. 在这个手册里,声明合并是指编译器会

转载:《TypeScript 中文入门教程》 2、枚举

版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 由于第一章节是我翻译的,而且与他的版本不一致,导致第一章节有枚举这部分,而他的第二章节也有这部分,但内容不同,所以我保留了这部分. 枚举 使用枚举我们可以定义一些有名字的数字常量. 枚举通过使用enum关键字定义. enum Direction { Up = 1, Down, Left, Right } 一个枚举类型可以包含零个或多个枚举成员. 枚举成员具有一个数字值,它们可以是常数

转载:《TypeScript 中文入门教程》 17、注解

版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 随着TypeScript和ES6里引入了类,现在在一些场景下我们会需要额外的特性来支持注解或修改类和类成员. Decorators提供了一种方式来添加注解和在类的声明和成员上使用元编程语法. Javascript里的Decorators目前处在建议征集的第一阶段,在TypeScript里做为实验性特性已经提供了支持. 注意  Decorators是实验性的特性,在未来的版本中可

转载:《TypeScript 中文入门教程》 15、可迭代性

版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 可迭代性 当一个对象实现了Symbol.iterator属性时,我们认为它是可迭代的. 一些内置的类型如Array,Map,Set,String,Int32Array,Uint32Array等都已经实现了各自的Symbol.iterator. 对象上的Symbol.iterator函数负责返回供迭代的值. for..of 语句 for..of会遍历可迭代的对象,调用对象上的Symbo

转载:《TypeScript 中文入门教程》 16、Symbols

版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 至ECMAScript 2015开始,symbol成为了一种新的原始类型,就像number和string一样. symbol类型的值是通过Symbol构造函数创建的. var sym1 = Symbol(); var sym2 = Symbol("key"); // 可选的字符串key Symbols是不可改变的且唯一. var sym2 = Symbol("

《TypeScript 中文入门教程》 1、基础数据类型

转载:https://github.com/MyErpSoft/TypeScript-Handbook/blob/master/pages/zh-CHS/Basic%20Types.md 概述 为了让程序更易用,我们兼容几种最基本的数据类型:numbers(数字),strings(字符串),structures(结构),boolean(布尔值)等等.在 TypeScript 中,我们支持和 Javascript 几乎一样多的类型,并且新增了实用的枚举类型. Boolean 布尔值 最基础的数据类