Ryan Florence
Ryan Florence

Reputation: 13483

Instantiate a Class dynamically via variable

How can I instantiate a class by throwing in a variable name? Consider this method inside a class:

animate: function(el, build) { 
        console.log(build.effect); 
        var animationClass = new build.effect(el,build); 
}, 

Build is an object containing lots of stuff, but most importantly an "effect". This effect is the name of an independent animation class-- one is called "MarioKartMenu".

console.log(build.effect) prints out "MarioKartMenu". But of course I get: TypeError: Result of expression 'build.effect' [MarioKartMenu] is not a constructor.

If I trash the dynamism and just make the code as such:

animate: function(el, build) {
        var animationClass = new MarioKartMenu(el,build);
    }, 

It works just fine. Is it possible to make it dynamic like I'm attempting to do?

Upvotes: 6

Views: 5990

Answers (3)

sth
sth

Reputation: 229633

Just assign the constructor to build.effect (not a string containing its name) and it should work:

animate = function(el, build) {
    var animationClass = new build.effect(el,build);
}
// ...

b = ...;
b.effect = MarioKartMenu;
animate(e, b);

Upvotes: 3

staticsan
staticsan

Reputation: 30555

My first thought is to use JavaScript's eval() operator, though I understand this is a less than elegant solution. (Soemthing like this: var animationClass = eval("new "+build.effect+"(el, build)"); although I'm not sure that's correct as I haven't used eval() like this before.). Ayman's answer is a much better variation on this idea.

My second thought is that MarioKartMenu isn't suitably abstracted. So I'd build a simple class around it that takes the effect name as a third parameter and uses a switch() statement to select amongst all the available effects, instantiates the correct one and returns it.

Upvotes: 0

Ayman Hourieh
Ayman Hourieh

Reputation: 137196

If the function MarioKartMenu is defined in the global scope, you can access it by its string name using:

window["MarioKartMenu"]

This works because all global variables are properties of the window object.

Given the above, you can implement what you want by using:

var menuConstructor = window[build.effect];
var animationClass = new menuConstructor(el, build);

Upvotes: 5

Related Questions