这是否特别强大(尝试检测' new'关键字是否用于创建对象)?
this.constructor.toString().indexOf('window') === -1
请记住,我并不太关心像IE6 / 7/8这样的古老浏览器。
答案 0 :(得分:2)
不,它不仅不健全,而且不正确。它在构造函数中的任何位置查找字符"window"
,这会给出两个误报(你可以在没有new
的情况下调用没有"window"
的函数)和假阴性(只是因为构造函数包含"window"
,这并不意味着它没有使用new
调用。)
在ES5及更早版本中,您完全不能完全确定 new
,但您可以与以下内容保持足够接近:
if (this instanceof TheConstructorName) {
// Yes, `new` was probably used
}
......但这可能会被打败:
var f = new TheConstructorName(); // Really called with `new`
TheConstructorName.call(f); // Tricks it
如果您使用严格模式,this
如果有人undefined
,则TheConstructorName()
为this
,但您不能仅依赖undefined
TheConstructorName.call({})
,因为有人可以执行var o = {c: TheConstructorName}; o.c();
甚至this
,其中任何一个都将undefined
设置为if (new.target) {
// Yes, `new` was used
}
以外的值,即使在严格模式下也是如此。
在ES2015 +中,您可以通过查看new.target
:
class
但是,如果使用class
语法,则不需要这样做;使用new
创建的构造函数不能在没有super
的情况下调用(直接或间接调用var res = {};
)。
答案 1 :(得分:1)
你有几个解决方案来检查这个......
function Foo() {
if (!(this instanceof Foo)) {
throw new Error('Oops!');
}
console.log('OK');
}
new Foo(); // OK
Foo(); // Error
function Foo() {
if (this.constructor !== Foo) {
throw new Error('Oops!');
}
console.log('OK');
}
new Foo(); // OK
Foo(); // Error
function Foo() {
if (!new.target) {
throw new Error('Oops!');
}
console.log('OK');
}
new Foo(); // OK
Foo(); // Error
答案 2 :(得分:0)
如前所述,instanceof
是检测是否使用new
关键字的一种非常好的方法。以下是您可以使用的一些代码,以防有人忘记new
关键字,因此他们不会得到奇怪的结果:
function Foo(bar) {
if (!(this instanceof Foo)) {
return new Foo(bar)
}
this.bar = bar
return this
}
new Foo(1, 2) // OK
Foo(3, 4) // OK