如果未使用新运算符,则返回新对象

时间:2012-05-07 20:52:48

标签: javascript oop google-chrome object v8

我在名为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

4 个答案:

答案 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);

作为小提琴:http://jsfiddle.net/YSEFK/

答案 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