Justin Fagnani décrit une manière très propre (à mon humble avis) de composer plusieurs classes en une en utilisant le fait que dans ES2015, les classes peuvent être créées avec des expressions de classe .
Expressions vs déclarations
En gros, tout comme vous pouvez créer une fonction avec une expression:
function myFunction() {} // function declaration
var myFunction = function(){} // function expression
vous pouvez faire la même chose avec les classes:
class MyClass {} // class declaration
var MyClass = class {} // class expression
L'expression est évaluée à l'exécution, lorsque le code s'exécute, alors qu'une déclaration est exécutée au préalable.
Utilisation d'expressions de classe pour créer des mixins
Vous pouvez l'utiliser pour créer une fonction qui crée dynamiquement une classe uniquement lorsque la fonction est appelée:
function createClassExtending(superclass) {
return class AwesomeClass extends superclass {
// you class body here as usual
}
}
Ce qui est cool, c'est que vous pouvez définir la classe entière à l'avance et ne décider que de la classe à étendre au moment où vous appelez la fonction:
class A {}
class B {}
var ExtendingA = createClassExtending(A)
var ExtendingB = createClassExtending(B)
Si vous souhaitez mélanger plusieurs classes ensemble, étant donné que les classes ES6 ne prennent en charge qu'un seul héritage, vous devez créer une chaîne de classes contenant toutes les classes que vous souhaitez mélanger. Alors disons que vous voulez créer une classe C qui étend à la fois A et B, vous pouvez faire ceci:
class A {}
class B extends A {}
class C extends B {} // C extends both A and B
Le problème, c'est que c'est très statique. Si vous décidez par la suite que vous voulez créer une classe D qui étend B mais pas A, vous avez un problème.
Mais avec une astuce intelligente utilisant le fait que les classes peuvent être des expressions, vous pouvez résoudre ce problème en créant A et B non pas directement en tant que classes, mais en tant que fabriques de classes (en utilisant les fonctions fléchées par souci de concision):
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)
Remarquez que nous ne décidons qu'au dernier moment quelles classes inclure dans la hiérarchie.