Джастин Фагнани описывает очень чистый (imho) способ объединения нескольких классов в один, используя тот факт, что в ES2015 классы можно создавать с помощью выражений классов .
Выражения против деклараций
По сути, так же, как вы можете создать функцию с выражением:
function myFunction() {} // function declaration
var myFunction = function(){} // function expression
вы можете сделать то же самое с классами:
class MyClass {} // class declaration
var MyClass = class {} // class expression
Выражение оценивается во время выполнения, когда выполняется код, тогда как объявление выполняется заранее.
Использование выражений класса для создания миксинов
Вы можете использовать это для создания функции, которая динамически создает класс только при вызове функции:
function createClassExtending(superclass) {
return class AwesomeClass extends superclass {
// you class body here as usual
}
}
Самое замечательное в этом то, что вы можете заранее определить весь класс и решить, какой класс он должен расширять, только к моменту вызова функции:
class A {}
class B {}
var ExtendingA = createClassExtending(A)
var ExtendingB = createClassExtending(B)
Если вы хотите смешать несколько классов вместе, поскольку классы ES6 поддерживают только одиночное наследование, вам необходимо создать цепочку классов, содержащую все классы, которые вы хотите смешать вместе. Допустим, вы хотите создать класс C, расширяющий как A, так и B, вы можете сделать это:
class A {}
class B extends A {}
class C extends B {} // C extends both A and B
Проблема в том, что он очень статичен. Если позже вы решите, что хотите создать класс D, расширяющий B, но не A, у вас возникнет проблема.
Но с помощью некоторых хитрых уловок, использующих тот факт, что классы могут быть выражениями, вы можете решить эту проблему, создав A и B не напрямую как классы, а как фабрики классов (с использованием стрелочных функций для краткости):
class Base {} // some base class to keep the arrow functions simple
var A = (superclass) => class A extends superclass
var B = (superclass) => class B extends superclass
var C = B(A(Base))
var D = B(Base)
Обратите внимание, как мы только в последний момент решаем, какие классы включить в иерархию.