Search code examples
javascriptoopgoogle-chromeobjectv8

Returning a new object if new operator wasn't used


I have got a "class" (function) in js named Foo that create objects. As it is used very frequently, I want it to avoid requiring the new keywoard being used when new instances of it are to be created: Foo(something); instead of new Foo(something);.

I got this to work in Firefox with:

function Foo(arg) {
    if (this instanceof Window)
        return new Foo(arg);

    //Object construction here.
    this.bar = "Hello " + arg;
}

Now I can create instances of Foo just by calling it as a function.

console.log(Foo("World").bar); //Output "Hello World" in console.

While this is working in FF, it does not in Chrome and I did not dare testing IE yet.

The problem in chrome is that window is really of type DOMWindow in chrome

Uncaught ReferenceError: Window is not defined

and this instanceof DOMWindow does not work in chrome because for some reason it gives:

ReferenceError: DOMWindow is not defined

I have also tried using !(this instanceof Foo) and typeof this always seems to give "object".

How can I reliably detect if the new keyword was omitted when calling Foo on all browsers?

Update: !(this instanceof Foo) does work, I just had a stray return this in my real Foo function.


Solution

  • Testing this being an instanceof Foo works in Chrome 20, FF 12, and IE 8, and should work fine:

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

    As a fiddle : http://jsfiddle.net/YSEFK/