概要
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