有没有办法防止在JavaScript中将新定义的函数作为构造函数调用?就像在调用之前放置new
时抛出错误一样。
您可以通过查看函数是否是自身的实例来检查该函数是否被new
调用
function test() {
if ( this instanceof test ) {
throw "Oh God no, not a new one !"
}
}
var a = test(); // success
var b = new test(); // fail
在 ES2015 中,new.target
meta 属性允许您直接检查是否使用了new
来调用该方法
function test() {
if (new.target) {
throw "Oh God no, not a new one !"
}
}
您可以在函数中检查this.constructor
:
function f() {
if (this && this.constructor === f) {
throw new Error("Don't call f as a constructor")
}
}
f(); // ok
new f(); // throws
正如@squint指出的,如果显式设置f.prototype.constructor
,则可以中断此检查:
f.prototype = {
constructor: "not f!"
}
new f(); // doesn't throw
如果您的环境支持它们,您可以使用箭头函数:
const f = () => "test"
f() // returns "test"
new f() // throws TypeError: f is not a constructor(…)
请注意,箭头函数从定义它们的作用域继承this
。这与function
不同(this
通常取决于函数的调用方式(,因此您不能总是将它们用作直接替代品。
如果箭头函数作为构造函数调用,Babel 当前不会引发异常:Babel REPL 示例。
箭头函数兼容性表