One of my favorite pieces of code to use is:
if (!(eval("this instanceof "+arguments.callee.name)))
return eval("new "+arguments.callee.name+"(...arguments)");
This piece of code allows function prototypes to create themselves when set like getting the result of themselves as a regular function. (Removes the requirement to type 'new' for function prototypes)
However, that it uses eval. Is there any way to remove eval from it?
Also, is there a way to shorten it further?
Yes, there's no need for
evalthere. Here's how you'd do it in modern environments (ES2015+):That avoids using
eval, theargumentspseudo-array, and alsoarguments.callee, which should never be used and which is disallowed in strict mode. (Strict mode is the default in modules and classes and will be the default in any further new scopes added to the language.)You could keep using the
argumentspseudo array if you like:FWIW, I strongly recommend not making a function dual-use like that. Instead, consider using
classsyntax and acreatefunction for when you don't want to usenew:If you try to do
Example(1, 2), an error is automatically thrown becauseclassconstructors can't be called as though they were normal functions. You can avoidnewby usingExample.create(1, 2)instead.The version of
createthat usesthisavoids explicitly naming the constructor:That works because when you do
Example.create(1, 2), during the call tocreatethisrefers toExample.But it won't work if you do passExample.createaround without ensuring it's bound. For instance,const create = Example.create; create(1, 2);would fail withnew this(...)but would work withnew Example(..).