18
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ES6 class の動的継承を使った mixin

Last updated at Posted at 2015-07-28

概要

ES6 の class は、構文レベルで mixin をサポートしていないので、mixin を実現するにはプログラム的にclassを操作する必要がある。
やり方は色々あると思うのだが、 動的に継承元を変えられるクラスを作ることでmixinを実現する というわりととシンプルな方法を思いついた。

できること

  • 任意のクラス間で共通のconstructor、メソッド等を共有
  • super 呼び出し
  • 複数mixinの組み合わせ

できないこと

  • instanceof

やりかた

基本

// baseが無いときは何も継承しない
function mixin(base = null) {
  class Mixin extends base {
    method() {
      console.log("Mixin method");
    }
  }
  return Mixin;
}

class Base {
}

class Derived extends mixin(Base) {
}

const derived = new Derived();
derived.method();
// Mixin method

super を使う

function mixin(base = null) {
  class Mixin extends base {
    constructor() {
      super();
      console.log("init Mixin");
    }
    method() {
      super.method();
      console.log("Mixin method");
    }
  }
  return Mixin;
}

class Base {
  constructor() {
    console.log("init Base");
  }
  method() {
    console.log("Base method");
  }
}

class Derived extends mixin(Base) {
  constructor() {
    super();
    console.log("init Derived");
  }
}

const derived = new Derived();
// init Base
// init Mixin
// init Derived

derived.method();
// Base method
// Mixin method

複数mixin

function mixin1(base = null) {
  class Mixin1 extends base {
    method1() {
      console.log("method1");
    }
  }
  return Mixin1;
}

function mixin2(base = null) {
  class Mixin2 extends base {
    method2() {
      console.log("method2");
    }
  }
  return Mixin2;
}

class Base {
}

class Derived extends mixin2(mixin1(Base)) {
}

const derived = new Derived();
derived.method1();
derived.method2();
// method1
// method2

ほかのmixinをmixinしたmixin

function mixin1(base) {
  class Mixin1 extends base {
    method1() {
      console.log("method1");
    }
  }
  return Mixin1;
}

function mixin2(base) {
  class Mixin2 extends mixin1(base) {
    method2() {
      console.log("method2");
    }
  }
  return Mixin2;
}

class Base {
}

class Derived extends mixin2(Base) {
}

const derived = new Derived();
derived.method1();
derived.method2();
// method1
// method2
18
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?