Justin Fagnani opisuje bardzo czysty (imho) sposób komponowania wielu klas w jedną, wykorzystując fakt, że w ES2015 klasy można tworzyć za pomocą wyrażeń klas .
Wyrażenia a deklaracje
Zasadniczo, tak jak możesz utworzyć funkcję z wyrażeniem:
function myFunction() {}
var myFunction = function(){}
możesz zrobić to samo z zajęciami:
class MyClass {}
var MyClass = class {}
Wyrażenie jest oceniane w czasie wykonywania, kiedy kod jest wykonywany, podczas gdy deklaracja jest wykonywana wcześniej.
Używanie wyrażeń klas do tworzenia połączeń
Możesz użyć tego do stworzenia funkcji, która dynamicznie tworzy klasę tylko wtedy, gdy funkcja jest wywoływana:
function createClassExtending(superclass) {
return class AwesomeClass extends superclass {
}
}
Fajną rzeczą jest to, że możesz wcześniej zdefiniować całą klasę i zdecydować, którą klasę ma ona rozszerzyć do czasu wywołania funkcji:
class A {}
class B {}
var ExtendingA = createClassExtending(A)
var ExtendingB = createClassExtending(B)
Jeśli chcesz mieszać wiele klas razem, ponieważ klasy ES6 obsługują tylko pojedyncze dziedziczenie, musisz utworzyć łańcuch klas zawierający wszystkie klasy, które chcesz ze sobą mieszać. Powiedzmy, że chcesz utworzyć klasę C, która rozszerza zarówno A, jak i B, możesz to zrobić:
class A {}
class B extends A {}
class C extends B {}
Problem polega na tym, że jest bardzo statyczny. Jeśli później zdecydujesz, że chcesz stworzyć klasę D, która rozszerza B, ale nie A, masz problem.
Ale z pewną sprytną sztuczką wykorzystującą fakt, że klasy mogą być wyrażeniami, możesz rozwiązać ten problem, tworząc A i B nie bezpośrednio jako klasy, ale jako fabryki klas (używając funkcji strzałek dla zwięzłości):
class Base {}
var A = (superclass) => class A extends superclass
var B = (superclass) => class B extends superclass
var C = B(A(Base))
var D = B(Base)
Zwróć uwagę, że dopiero w ostatniej chwili decydujemy, które klasy uwzględnić w hierarchii.