0

I have a JS class that takes in several arguments:

var MyClassName = function(arg1, arg2, arg3){ // Do stuff };

I have a String that represents the class's name, and an array of arguments.

var class = "MyClassName"
var args = ["1", "2", "3"]

Using the String of the class name and the array of arguments, how can I instantiate the class? Prototype Bind/apply seems to have some relevance, but I can't quite figure out how this all works together. I've also tried using window["MyClassName"], but that throws an undefined error. Any suggestions?

7
  • possible duplicate of What techniques can be used to define a class in JavaScript, and what are their trade-offs? Commented Jun 1, 2015 at 23:19
  • Sorry, then I didn't unterstand your answer. Commented Jun 1, 2015 at 23:25
  • To clarify, I'm trying instantiate a new instance of a class based on a string of the class's name. The class takes several arguments, but I only want to pass it an array or arguments. Commented Jun 1, 2015 at 23:26
  • Edit: Wrong answer again.. I should go to bed. Commented Jun 1, 2015 at 23:32
  • Can you explain the reason for doing this? That might help someone offer a better solution. Commented Jun 1, 2015 at 23:51

3 Answers 3

1

You can use eval:

var a = eval("new " + className + " ( " + arguments.toString() + ")");

Example:

JSFIDDLE: https://jsfiddle.net/s40ave7r/

function A(a1,a2,a3) {
    this.a1 = a1;
    this.a2 = a2;
    this.a3 = a3;
}

var className = "A";
var arguments = [1,2,3];

var a = eval("new " + className + " ( " + arguments.toString() + ")");

console.log(a); // A {a1:1, a2:2, a3:3}

Note:

Using eval in general is a bad idea. If you can try to avoid it. These are some problems related to eval:

  1. Improper use of eval opens up your code for injection attacks
  2. Debugging can be more challenging (no line numbers, etc.)
  3. eval'd code executes more slowly (no opportunity to compile/cache eval'd code)

Solution 2

Other solution is to attach the class definition to an object. For example, when you define a class in the global scope this is attached by default to the window object in the browser, or to the global object in node. So you can do :

Browser

function MyClass() {}
new window["MyClass"](arg1, arg2..);

Node

function MyClass() {}
new window["MyClass"](arg1, arg2..);
Sign up to request clarification or add additional context in comments.

Comments

1

You can define your 'class' as

window.MyClassName = function( arg1, arg2, ... ) {
    this.arg1 = arg1;
    //...
};

then you can call it with

var instance = new window['MyClassName']( arg1, arg2, ... ) 

or with

var instance = new window.MyClassName( arg1, arg2, ... );

or better don't use window, use an own object.

var classes = {
    MyClassName: function( arg1, arg2, ... ) {
        this.arg1 = arg1;
        //...
    }
};

var instance = new classes.MyClassName( arg1 );

Edit: You said window["MyClassName"] didn't work, but if you define a 'class' in the global scope, then you can call it like this. Can you please add the error you meant?

function testClass( arg1 ) {
    this.foo = arg1;
}

var instance = new window['testClass']( 'bar' );
console.log( instance.foo ); // The output will be bar

This code is working, but probably you forgot the 'new'. If you try this without the 'new', then it throws this error at Chrome:

Uncaught TypeError: Cannot read property 'foo' of undefined

Comments

0

Thank you all for the wonderful suggestions. I combined part of the answers here in addition to this SO answer:

var className = new window['MyClassName'] var instantiatedClass = className.bind.apply(className, [null, arg1, arg2, ...]);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.