Reputation: 3522
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
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
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