Is there a way to prevent a new defined function to be called as constructor in JavaScript? Like throw out error when placing new before calling it.
3 Answers
You can check if a function was called with new by seeing if it is an instance of itself
function test() {
if ( this instanceof test ) {
throw "Oh God no, not a new one !"
}
}
var a = test(); // success
var b = new test(); // fail
In ES2015 the new.target meta property lets you check directly if new was used to call the method
function test() {
if (new.target) {
throw "Oh God no, not a new one !"
}
}
Comments
You could check this.constructor inside the function:
function f() {
if (this && this.constructor === f) {
throw new Error("Don't call f as a constructor")
}
}
f(); // ok
new f(); // throws
As @squint points out, it is possible to break this check if f.prototype.constructor is set explicitly:
f.prototype = {
constructor: "not f!"
}
new f(); // doesn't throw
2 Comments
If your environment supports them, you could use an arrow function:
const f = () => "test"
f() // returns "test"
new f() // throws TypeError: f is not a constructor(…)
Note that arrow functions inherit this from the scope that they are defined in. That's different from function (where this usually depends on how the function is called), so you can't always use them as a drop-in replacement.
Babel currently does not throw an Exception if an arrow function is called as a constructor: Babel REPL example.
new.targetin a function to determine ifnewwas used to invoke it.console.log(new.target)will showundefinedifnewwas not used, otherwise you get a reference to the function itself.