James Allardice
James Allardice

Reputation: 166021

Why are null and undefined of the type DOMWindow?

When you run the following code in the browser, or in Node.js, you get the expected outcomes listed in the comments:

Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"

When you run that code in PhantomJS, however, the output is [object DOMWindow] in both cases.

This seems strange, since undefined and null are both native types. The typeof operator appears to work as it does in other environments (including the typeof null === "object" quirk), so it would appear that PhantomJS does at least have the concept of the undefined type:

typeof undefined; // "undefined"

It also claims that Object.prototype.toString contains native code, which may indicate that Phantom itself isn't doing anything to modify the implementation (I don't know if that's the case or not though - I haven't been able to find anything useful in the source):

Object.prototype.toString.toString(); // "function toString() { [native code] }"

So why does PhantomJS not use (or at least expose) the correct [[Class]] property values for null and undefined, and is there a way I change that? I know I could use a different method to determine type, but I'd rather not have to.

Upvotes: 10

Views: 700

Answers (3)

millimoose
millimoose

Reputation: 39970

I'll admit I'm kind of reaching here, but the MDN article on Object.toString() mentions:

Starting in JavaScript 1.8.5 toString() called on null returns [object Null], and undefined returns [object Undefined], as defined in the 5th Edition of ECMAScript and a subsequent Errata. See Using toString to detect object type.

The linked section then describes the construct Object.prototype.toString(null) that you're using. So it seems like being able to sensibly stringify null and undefined is a new(-ish) addition/correction to Javascript that the PhantomJS engine (Apple's JavaScriptCore, at who knows which version) doesn't implement yet. That said, this works correctly in Safari 6, so it might be worth to report this as a bug, asking for ES5 compliance.

Upvotes: 0

Ariya Hidayat
Ariya Hidayat

Reputation: 12561

It is a combination of two things. A script is executed within a web page and therefore the global object is the window object, as evidenced from:

console.log(this.toString()); // [object DOMWindow]

In addition, there is a problem with that version of JavaScript implementation which falsifies the object prototype chain under the above condition.

This is likely going to be fixed in some future version.

Upvotes: 7

José Gómez
José Gómez

Reputation: 112

if it's just that 2 types, i think you can just surround your issue with this.

Object.prototype.toString = function(obj){

    if(typeof(obj) == "undefined"){
        return "[object Undefined]";
    }

    if(typeof(obj) == "null"){
        return "[object Null]";
    }

    return obj.toString();

}

Upvotes: -1

Related Questions