Créer une instance d'une classe dans ES6 avec un nom dynamique?

Je souhaite pouvoir instancier une classe ES6 particulière en passant une variable de chaîne à une fonction. Selon la valeur de la variable, une classe différente sera créée.

Exemple – J'ai 2 classes, ClassOne , ClassTwo . Je veux pouvoir passer une variable à une fonction et récupérer une nouvelle classe. Le nom de la classe sera lié à la variable – par exemple. Le passage 'Two' créera ClassTwo .

Je ne veux pas utiliser une clause de switch comme celle-ci:

 function createRelevantClass( desiredSubclassName ) { let args = [], newClass; switch( desiredSubclassName ) { case 'One' : newClass = new ClassOne(args); break; case 'Two' : newClass = new ClassTwo(args); break; } return newClass; } 

Au lieu de cela, je veux en quelque sorte être en mesure de créer l'appel du constructeur en utilisant le nom de la variable. Est-ce possible?

 function createRelevantClass( desiredSubclassName ) { // desiredSubclassName would be string 'One' or 'Two' // how to use the 'new' operator or Reflect here to create the class based on the variable passed in let newClass = ( *magic code to build constructor dynamically* ); return newClass; } 

Il y a quelques façons d'accomplir ceci …

1. Classe de procuration

À partir de l'exemple de TheFourtheye, en maintenant un mappage de nom en classe, vous pourriez avoir une classe dont le travail consiste à prendre le nom de la classe souhaitée et à lui proposer son instanciation:

[ Voyez-le fonctionner ]

Définissez vos cours

 // ClassOne.js export class ClassOne { constructor () { console.log("Hi from ClassOne"); } } // ClassTwo.js export class ClassTwo { constructor (msg) { console.log(`${msg} from ClassTwo`); } } 

Définissez la classe proxy (p. Ex. DynamicClass )

 import ClassOne from './ClassOne'; import ClassTwo from './ClassTwo'; // Use ES6 Object Literal Property Value Shorthand to maintain a map // where the keys share the same names as the classes themselves const classes = { ClassOne, ClassTwo }; class DynamicClass { constructor (className, opts) { return new classes[className](opts); } } export default DynamicClass; 

Exemple d'utilisation

 import DynamicClass from './DynamicClass'; new DynamicClass('ClassOne'); //=> "Hi from ClassOne" new DynamicClass('ClassTwo', 'Bye'); //=> "Bye from ClassTwo" 

2. Fonction d'usine

Utilisez une fonction qui effectue une recherche sur un objet de nom de classe -> mappages de classe et renvoie la référence à la classe, que nous pouvons alors instancier comme d'habitude.

Définir la fonction d'usine

 import ClassOne from './ClassOne'; import ClassTwo from './ClassTwo'; const classes = { ClassOne, ClassTwo }; export default function dynamicClass (name) { return classes[name]; } 

Exemple d'utilisation

 import dynamicClass from './dynamicClass' const ClassOne = dynamicClass('ClassOne') // Get the ClassOne class new ClassOne(args) // Create an instance of ClassOne 

Stockez les classes dans un objet, les clés étant les noms des classes que vous souhaitez qu'elles soient.

 const classesMapping = { 'One': ClassOne, 'Two': ClassTwo }; 

Puis créez la classe en fonction du nom de la clé comme celui-ci

 return new classesMapping[desiredSubclassName](args);