Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
35
rated 0 times [  42] [ 7]  / answers: 1 / hits: 67257  / 9 Years ago, thu, january 7, 2016, 12:00:00

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;
}

More From » class

 Answers
27

There are a few ways you can accomplish this...



1. Proxy Class



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


2. Factory Function



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

[#63810] Tuesday, January 5, 2016, 9 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
tobyl

Total Points: 598
Total Questions: 110
Total Answers: 114

Location: Vietnam
Member since Sat, Feb 12, 2022
2 Years ago
;