0

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?

6
  • nameFunction returns an object, not a function? If you would like to use new it should return a class or a "regular" function (not an arrow function). Commented Mar 16, 2021 at 20:44
  • @evolutionxbox how is b in the code given an arrow function? How do you show that it is an object? typeof b === 'function' Commented Mar 16, 2021 at 20:48
  • You're right. It's not an arrow function (I didn't say it was). My recommendation is to return a class or regular function. Commented Mar 16, 2021 at 20:49
  • @evolutionxbox but I want the name of the created object to be dynamic Commented Mar 16, 2021 at 20:50
  • I couldn't really figure out why the function being returned wasn't a constructor function. It is most likely be due to the fact it's being made inside an object. Commented Mar 16, 2021 at 21:03

2 Answers 2

2

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));

Sign up to request clarification or add additional context in comments.

Comments

1

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

1 Comment

I'm not sure this entirely works? b = nameFunction('c', function () { this.x = 'x' }); new b() // Object { } <- no x property?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.