Gabriel Furstenheim
Gabriel Furstenheim

Reputation: 3522

Dynamic constructor name in js

I want to do exactly the same as this question but use the function as a constructor.

> function nameFunction(name, body) {
   return {[name](...args) {return body(...args)}}[name]
}

> b = nameFunction('c', function () {})
[Function: c]
> typeof b
'function'

b is a function, yet it is not a constructor:

> new b()
Uncaught TypeError: b is not a constructor

If done in the standard way, it is a constructor:

> b = function() {}
[Function: b]
> new b()
b {}

But the name is b, not c.

How can I build a constructor with the given name and not using eval?

Upvotes: 0

Views: 431

Answers (2)

Aadit M Shah
Aadit M Shah

Reputation: 74244

The answer provided by georg is correct but incomplete. In order to use the dynamically named function as a constructor, not only do you need to use an ordinary function but also you need to preserve the this context. We can do this by applying this and arguments to the body as follows.

function nameFunction(name, body) {
    const object = {
        [name]: function () {
            return body.apply(this, arguments);
        }
    };

    return object[name];
}

const Bar = nameFunction("Foo", function (foo) {
    this.foo = foo;
});

console.log(Bar.name, new Bar(42));

Upvotes: 2

georg
georg

Reputation: 215029

Methods are not constructors (see https://262.ecma-international.org/7.0/#sec-functioncreate and https://262.ecma-international.org/7.0/#sec-functionallocate). Just define it as an ordinary function:

function nameFunction(name, body) {
   return {[name]: function(...args) {return body(...args)}}[name]
}

b = nameFunction('c', function () {})

new b

Upvotes: 1

Related Questions