js實現多繼承

/*保證typescript能夠正確計算類型*/
export function extend<T, U>(target: Type<T>, source1: Type<U>): Type<T & U>;
export function extend<T, U, V>( target: Type<T>, source1: Type<U>, source2: Type<V> ): Type<T & U & V>;
export function extend<T, U, V, W>( target: Type<T>, source1: Type<U>, source2: Type<V>, source3: Type<W> ): Type<T & U & V & W>;
export function extend<T, U, V, W, X>( target: Type<T>, source1: Type<U>, source2: Type<V>, source3: Type<W>, source4: Type<W> ): Type<T & U & V & W & X>;
/*結束*/


/*功能*/
export function extend(target: Type<any>, ...sources: Type<any>[]): Type<any> {
  return extend2(target)(...sources.reverse());
}

function extend2(target: Type<any>) {
  return (...sources: Type<any>[]): Type<any> => {
    let targetPrototype = target.prototype;
    // 繼承
    (function() {
      // 建立一個乾淨的實例
      function beget() {
        var F = function() {
          // sources屬性處理
          sources.map(source => source.call(this));
        };
        // sources處理
        assign(F.prototype, ...sources.map(source => source.prototype));
        return new F();
      }
      let prototype = beget();
      prototype.constructor = target;
      // 繼承
      target.prototype = prototype;
      // 原來的方法
      assign(target.prototype, targetPrototype);
    })();
    return target as any;
  };
}
/*結束*/
複製代碼

測試typescript

import { expect } from "chai";
import { extend } from "./extend";
export class A {
  title: string = "a";

  run() {
    return "a";
  }
}
export class B {
  title: string = "b";
  demo: string = "demo";

  add() {
    return "b";
  }
}
export class D {
  title: string = "d";
  console() {
    return "d";
  }
}

let C = extend(A, B, D);
const c = new C();

describe("extend", () => {
  it("c.demo", () => {
    expect(c.demo).equal("demo");
  });
  it("c.add", () => {
    expect(c.add()).equal("b");
  });
  it("c.add", () => {
    expect(c.run()).equal("a");
  });
  it("c.add", () => {
    expect(c.console()).equal("d");
  });
});
複製代碼
相關文章
相關標籤/搜索