I want to be able to instantiate a particular ES6 class by passing a string variable to a function. Depending on the value of the variable, a different class will be created.
Example - I have 2 classes, ClassOne
, ClassTwo
. I want to be able to pass a variable to a function and get a new class back. The name of the class will be related to the variable - eg. passing 'Two'
will create ClassTwo
.
I don't want to just use a switch
clause like this:
function createRelevantClass( desiredSubclassName ) { let args = [], newClass; switch( desiredSubclassName ) { case 'One' : newClass = new ClassOne(args); break; case 'Two' : newClass = new ClassTwo(args); break; } return newClass; }
Instead, I want to somehow be able to create the constructor call using the variable name. Is that 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; }
There are a few ways you can accomplish this...
Following from @thefourtheye's example of maintaining a mapping of name to class, you could have a class whose job is to take the name of the desired class and proxy its instantiation:
[ See it working ]
Define your classes
// ClassOne.js export class ClassOne { constructor () { console.log("Hi from ClassOne"); } } // ClassTwo.js export class ClassTwo { constructor (msg) { console.log(`${msg} from ClassTwo`); } }
Define the proxy class (e.g. 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;
Example usage
import DynamicClass from './DynamicClass'; new DynamicClass('ClassOne'); //=> "Hi from ClassOne" new DynamicClass('ClassTwo', 'Bye'); //=> "Bye from ClassTwo"
Use a function that performs a lookup against an object of class name -> class mappings and returns reference to the class, which we can then instantiate as usual.
Define the factory function
import ClassOne from './ClassOne'; import ClassTwo from './ClassTwo'; const classes = { ClassOne, ClassTwo }; export default function dynamicClass (name) { return classes[name]; }
Example usage
import dynamicClass from './dynamicClass' const ClassOne = dynamicClass('ClassOne') // Get the ClassOne class new ClassOne(args) // Create an instance of ClassOne
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With