十五、Mixins

介绍

除了传统的面向对象继承方式,还有流行一种通过可重用组件创建类的方式,就是联合另一个简单类的代码

// TS中使用混入: Disposable Mixin
class Disposable {
  isDisposed: boolean;
  dispose() {
    this.isDisposed = true;
  }
}
// Activatable Mixin
class Activatable {
  isActive: boolean;
  activate() {
    this.isActive = true;
  }
  deactivate() {
    this.isActive = false;
  }
}

// 没使用extends而是使用implements。 把类当成了接口,仅使用Disposable和Activatable的类型而非其实现
class SmartObject implements Disposable, Activatable {
  constructor(){
    setInterval(() => {
      console.log(this.isActive + ' : ' + this.isDisposed)
    }, 500)
  }
  interact(){
    this.activate();
  }
  // 为将要mixin进来的属性方法创建出占位属性。 这告诉编译器这些成员在运行时是可用的。 这样就能使用mixin带来的便利,虽说需要提前定义一些占位属性
  isDisposed: boolean = false;
  dispose: () => void;
  isActive: boolean = false;
  activate: () => void;
  deactivate: () => void;
}

applyMixins(SmartObject, [Disposable, Activatable]);

let smartObj = new SmartObject();
setTimeout(() => {
  smartObj.interact()
}, 1000)
// 它会遍历mixins上的所有属性,并复制到目标上去,把之前的占位属性替换成真正的实现代码
function applyMixins (derivedCtor: any, baseCtors: any[]){
  baseCtors.forEach(baseCtors => {
    Object.getOwnPropertyNames(baseCtors.prototype).forEach(name => {
      derivedCtor.prototype[name] = baseCtors.prototype[name];
    })
  })
}

三斜线指令

三斜线指令是包含单个XML标签的单行注释,注释的内容会作为编译器指令使用
三斜线引用告诉编译器在编译过程中要引入的额外的文件

三斜线指令仅可以放在包含他的文件的最顶端,一个三斜线指令的前面只能出现单行或多行注释,这包括其他的三斜线指令

如果他出现在一个语句或声明之后,那么他们会被当做普通的单行注释,并且不具有特殊的含义

预处理输入文件:
解析:编译器会对输入文件进行预处理来解析所有三斜线引用指令,在这个过程中,额外的文件会加到编译过程中
查找:查找文件是以一些根文件开始(命令中指定文件或在tsconfig.json中的files列表里的文件),这些根文件按指定的顺序进行预处理。
处理顺序:三斜线引用以他们在文件里出现的顺序,使用深度优先的方式解析
错误:引用不存在的文件会报错,一个文件用三斜线指令引用自己会报错
noResolve:如果指定了noResolve编译选项,三斜线引用会被忽略,他们不会增加新文件,也不会改变给定文件的顺序

若要在.ts文件里声明一个对@types包的依赖,使用--types命令行选项或在tsconfig.json里指定

// 下面指令是三斜线指令中最常见的一种,它用于声明文件间的依赖
/// <reference path = "..." />
// 表明这个文件使用了 @types/node/index.d.ts里面声明的名字; 并且,这个包需要在编译阶段与声明文件一起被包含进来
// 仅当在你需要写一个d.ts文件时才使用这个指令
/// <reference types="node" />
// 这个指令把一个文件标记成默认库。 你会在 lib.d.ts文件和它不同的变体的顶端看到这个注释
/// <reference no-default-lib="true"/>
// 当一些工具需要处理生成的模块时会产生问题,比如 r.js。
// amd-module指令允许给编译器传入一个可选的模块名:
/// <amd-module />
///<amd-module name='NamedModule'/>

猜你喜欢

转载自blog.51cto.com/14533658/2436018