Create an object from its name without eval

I need to create an object from its name in Node.js. How can I do it (without using eval)?

For example, I've tried something like the code bellow, but it failed on `Person is unknown'. I guess it has something with the context (this). I tried the bind/call/apply functions, but with no avail.

module.export = {
    class Person =  {/*....*/};

    var createObject = function(name) {
        return Function('return new ' + name + '();')();

    const p1 = new Person(); // works
    const p2 = eval('return new Person();'); // works, but has security issues
    const p3 = createObject('Person'): // doesn't work.


I’d appreciate it if you could show me how to write the createObject function right.

4 answers

  • answered 2018-03-13 21:53 pushkin

    The stuff that you pass into Function doesn't get access to variables defined in the scope from where the constructor is called.

    See the source.

    Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope. When running them, they will only be able to access their own local variables and global ones, not the ones from the scope in which the Function constructor was called. This is different from using eval with code for a function expression.

    Though I'd be curious to know what your use case is. (I suppose my answer doesn't properly answer your question. It just explains why you're getting an error)

  • answered 2018-03-13 21:54 Fred Stark

    Why don't you create a map of creatable objects and lookup against it?


    const creatableObjects = {
      'Person': Person,
      'SomethingElse': SomethingElse
    const config = getConfig();
    const createdObject = new (creatableObjects[config.objectName])();

  • answered 2018-03-13 21:54 Ryan

    Create a map of names to constructors:

    const permittedTypes = new Map([
        ['Person', Person],
    const configuredType = 'Person';
    const p1 = new (permittedTypes.get(configuredType));

  • answered 2018-03-13 21:54 kingdaro

    Arbitrarily accessing variables using eval() or new Function() can lead to security issues, and isn't all that reliable either when the problem of scoping comes into question.

    What you can do instead is use an object with keys mapping to different classes, then reference the object using the specific key you want, so something like this:

    const classes = {
      Person: class Person {/* ... */},
      Dog: class Dog {/* ... */},
      Cat: class Cat {/* ... */},
    function createObject(className) {
      return new classes[className]()
    const p = createObject('Person') // returns a person

    One of the comments also suggested a switch statement, which would work as well. Whatever's cleaner.