How do I make JavaScript Object using a variable String to define the class name?
Would it work if you did something like this:
var myObject = window[classNameString];
..?
How to instantiate a Class from a String in JavaScript
One possibility is to use eval
.
class Foo {
constructor() {
console.log('Foo!');
}
};
const foo = 'Foo';
const bar = eval(`new ${foo}()`);
console.log(bar);
Create Class Definition from String
One way to achieve this is to add the text that instantiates the class to the string and only then eval
it:
const def = 'class M {}';
const instantiator = def + '; new M();';
const m = eval(instantiator);
EDIT:
To follow-up on the comment, if you want the class itself, it's even simpler - just add its name to the string you're evaluating:
const def = 'class M {}';
const statement = def + '; M;';
const M = eval(statement);
const m = new M(); // This now works!
Node.js - create object of class name specified in variable
If you're wishing to go with a more robust and testable approach, you could use a combination of classes and a factory pattern to issue the object. Check out the following, you'll see that with this setup, including more granular logic and testing down the road would come easier and afford you greater flexibility. You're also abstracting away new-ing up the object yourself behind the .issue
call - which can be beneficial and convenient in some cases.
I also notice that you mention your PHP background, so I'm also showcasing a bit of how an object orientated approach can be taken in ES6.
class AbstractShape {
constructor(type) {
this.type = type;
}
getType() {
console.log(`I am a ${this.type}`);
}
}
class Square extends AbstractShape {
constructor(type) {
super(type);
this.sides = 4;
}
getDescription() {
console.log(`I have ${this.sides} equal sides`);
}
}
class ShapeFactory {
static issue(type) {
switch(type) {
case 'Square': return new Square(type);
break;
case 'Circle': /* same pattern with a Circle class */
break;
}
}
}
let shape = ShapeFactory.issue('Square');
shape.getType(); /* I am a Square */
shape.getDescription(); /* I have 4 equal sides */
JSFiddle Link - demo
Furthermore, if you'd like something a bit more fault tolerant than dealing with redundant strings e.g. 'Square'
- there are some creative ways to leverage enum-like approaches that could refine this even further. I'll save the real estate here and not re-hash the code snippet, but will include a fiddle for you to check out.
JSFiddle Link - enum approach demo
ES6 class instance from string
Only global variables are put into window
automatically.
Create an object that maps from class names to classes:
const classMap = {
"MyClass": MyClass,
"MyClass2": MyClass2,
...
};
Then use classMap[name](params)
rather than window[name](params)
.
Call a class with a string in JavaScript
If you want to keep it as concise as you'd want, this is a case where you need to harness the evil powers of eval
, so that your code works whether it's invoked in the global scope or not:
class ClassA {}class ClassB {}
const classToInstantiate = 'ClassB';
const myInstance = eval(`new ${classToInstantiate}()`);
console.log(myInstance instanceof ClassB);
Create an instance of a class in ES6 with a dynamic name?
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
Related Topics
Fastest Way to Convert JavaScript Nodelist to Array
How to Get Current Value of Rxjs Subject or Observable
How to Make Exe Files from a Node.Js App
Looping Through an Object (Tree) Recursively
Can JavaScript Connect with MySQL
When and Where Does JavaScript Run, How About PHP? How to Combine the Two
How to Manually Trigger Validation with Jquery Validate
Jquery $("#Radiobutton").Change(...) Not Firing During De-Selection
How Filereader.Readastext in HTML5 File API Works
How to Detect a Long Touch Pressure with JavaScript for Android and Iphone
How to Check If a JavaScript Object Is a Dom Object
Jquery Checkbox Change and Click Event
How to Call Reduce on an Array of Objects to Sum Their Properties
How to Make JavaScript Object Using a Variable String to Define the Class Name
How to Check If an HTML Element Is Empty Using Jquery
How to Hide Form Code from View Code/Inspect Element Browser
How to Disable an <Option> in a <Select> Based on Its Value in JavaScript