TS从入门到放弃【十九】:混入

171 阅读2分钟

混入就是把两个对象或者类的内容混合到一起,从而实现功能复用

1、对象的混入

  • js 中对象的混入(实现两个对象的合并)
let a = { a: '1' }
let b = { b: '2' }
Object.assign(a, b)
console.log(a) // { a: '1', b: '2' }
console.log(b) // { b: '2' }
  • ts中对象的混入
interface ObjectA {
  a: string;
}
interface ObjectB {
  b: string;
}
let Aa: ObjectA = {
  a: 'a'
};
let Bb: ObjectB = {
  b: 'b'
};
let Ab = Object.assign(Aa, Bb);
console.log(Ab); // {a: 'a', b: 'b'}

可以把鼠标放在 Ab 上,看看它的类型:let Ab: ObjectA & ObjectB。其实就是一个交叉类型(既包含A的一些特性,又包含 B 的一些特性)

2、类的混入

  • js 中类的混入
class A {
  funcA() {
    console.log('aaa')
  }
}
class B {
  funcB() {}
}

我们已经定义了两个类:AB,现在我们再来定义 混入 函数:

const mixin = (target, from) => {
  // 获取对象自身的属性,除去它继承的属性
  Object.getOwnPropertyNames(from).forEach(key => {
    console.log(key)
    target[key] = from[key] // 把from的属性赋值到 target 上
  })
}
mixin(B.prototype, A.prototype)
const b = new B()
b.funcA() // aaa

把 A 的原型混入到 B 的原型对象上后,再实例化 B 后,实例 b 就拥有 A 的属性和方法了。

  • TS中类的混入

其实和 js 中差不多,但是 TS 中除了值还有类型的概念,所以简单的将属性复制到目标元素是不行的,还要处理对类型的定义。

创建两个类:ClassAaClassBb

class ClassAa {
  public isA: boolean;
  public funcA() {}
}
class ClassBb {
  public isB: boolean;
  public funcB() {}
}

接下来创建 ClassAB,将上面两个类作为接口来继承

class ClassAB implements ClassAa, ClassBb {
  public isA: boolean = false;
  public isB: boolean = false;
  constructor() {}
  public funcA: () => void;
  public funcB: () => void;
}

现在,我们来实现混合函数

function mixins(base: any, from: any[]) {
  from.forEach(fromItem => {
    Object.getOwnPropertyNames(fromItem.prototype).forEach(key => {
      console.log(key);
      base.prototype[key] = fromItem.prototype[key];
    });
  });
}

上述代码的打印顺序为:constructorfuncAconstructorfuncB

最后,我们来调用一下:

mixins(ClassAB, [ClassAa, ClassBb]);
const ab = new ClassAB();
console.log(ab); // ClassAB {isA: false, isB: false}