我在名为Foo
的js中创建了一个“类”(函数)来创建对象。由于它经常使用,我希望它避免在创建新实例时要求使用new
keywoard:Foo(something);
而不是new Foo(something);
。
我让它在Firefox中使用:
function Foo(arg) {
if (this instanceof Window)
return new Foo(arg);
//Object construction here.
this.bar = "Hello " + arg;
}
现在我可以通过将其作为函数调用来创建Foo的实例。
console.log(Foo("World").bar); //Output "Hello World" in console.
虽然这在FF中有效,但它不在Chrome中,我还不敢测试IE。
chrome中的问题是window
实际上是chrome中的DOMWindow
类型
Uncaught ReferenceError: Window is not defined
和this instanceof DOMWindow
在Chrome中不起作用,因为它出于某种原因它给出了:
ReferenceError: DOMWindow is not defined
我也尝试使用!(this instanceof Foo)
而typeof this
似乎总是给"object"
。
在所有浏览器上调用new
时,如何可靠地检测Foo
关键字是否被省略?
更新:!(this instanceof Foo)
确实有效,我的真实return this
函数中只有一个迷路Foo
。
答案 0 :(得分:2)
我没有测试过,但也许这样的东西会起作用吗?
var realWindow = this;
function Foo(arg) {
if (this === realWindow)
return new Foo(arg);
//Object construction here.
this.bar = "Hello " + arg;
}
您需要确保在任何范围之外声明realWindow
,以避免与this
发生冲突。
一般情况下,虽然 非常聪明,但我不建议只是为了节省几个字符的输入。它为未来的开发人员模糊了代码,通常不是很好的做法。
答案 1 :(得分:2)
测试这是Foo的一个实例在Chrome 20,FF 12和IE 8中有效,应该可以正常工作:
function Foo(arg) {
if (!(this instanceof Foo)) return new Foo(arg);
//Object construction here.
this.bar = "Hello " + arg;
}
var foo = Foo('World');
var baz = new Foo('Baz');
console.log(foo.bar);
console.log(baz.bar);
答案 2 :(得分:1)
如何反转条件?
function Foo(arg) {
if (!(this instanceof Foo))
return new Foo(arg);
//Object construction here.
this.bar = "Hello " + arg;
}
答案 3 :(得分:0)
您应该这样做的方法是根据自己的类型检查当前实例:
function Foo(...args...) {
if (!(this instanceof Foo)) {
return new Foo(...args...);
}
...do stuff...
}
它可以避免尝试检查全局对象,并且几乎可以在任何上下文中工作(尽管在其他情况下可能没有意义):
var a = {};
Foo.call(a);
这应该归还什么?在我的示例中,它将返回一个新的Foo
实例,但您可能不希望它创建一个新的Foo
。