2013-01-08 8 views
10

Wenn Sie den folgenden Code im Browser ausgeführt, oder in Node.js, erhalten Sie die in den Kommentaren aufgeführt erwarteten Ergebnisse:Warum sind null und undefiniert vom Typ DOMWindow?

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

Wenn Sie diesen Code in PhantomJS laufen, der Ausgang ist jedoch [object DOMWindow] in beide Fälle.

Dies scheint seltsam, seit undefined und null sind beide native Typen. Der typeof Operator scheint zu funktionieren, wie es in anderen Umgebungen funktioniert (einschließlich der typeof null === "object" Marotte), so scheint es, dass PhantomJS dest nicht an den Begriff des undefinierten Typ:

typeof undefined; // "undefined" 

Es behauptet auch, dass Object.prototype.toString enthält nativer Code, der anzeigen kann, dass Phantom selbst nichts tut, um die Implementierung zu ändern (ich weiß nicht, ob das der Fall ist oder nicht - ich konnte nichts Nützliches in der Quelle finden):

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

Warum verwendet PhantomJS nicht die korrekte?Eigenschaftswerte für null und undefined, und gibt es eine Möglichkeit, das zu ändern? Ich weiß, dass ich eine andere Methode verwenden könnte, um den Typ zu bestimmen, aber ich würde es lieber nicht tun müssen.

+6

Das klingt wie ein Fehler. – SLaks

+0

@SLaks - Ja, das war mein erster Gedanke, aber es ist nicht so, dass es ungewöhnlicher oder selten gefundener Code ist ... Ich bezweifle sehr, dass ich der Erste bin, der darauf stößt, und doch habe ich keinen Bezug darauf gefunden überall im Problem-Tracker. –

+0

Aus Neugier: Welche Art von Problemen versuchen Sie zu lösen oder welche Bedingungen sind von diesem Verhalten betroffen? –

Antwort

7

Es ist eine Kombination aus zwei Dingen. Ein Skript auf einer Webseite ausgeführt wird und somit das globale Objekt ist das window Objekt, belegte von:

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

Darüber hinaus gibt es ein Problem mit dieser Version der JavaScript-Implementierung, die die Objektprototypkette unter der fälscht obige Bedingung.

Dies wird wahrscheinlich in einer zukünftigen Version behoben werden.

+0

Danke für die Bereitstellung einer offiziellen Antwort :) Ich bemerkte, dass das globale Objekt" Fenster "war und angenommen, dass etwas damit zu tun hatte, aber durch die Quelle von Sowohl Phantom als auch JSC waren langweilig und brachten mich nirgendwohin. –

+1

Gibt es ein Problem in PhantomJS oder JSC? –

+0

Jeder gute Bug wird mit dem Alter noch besser - können Sie sich bitte über den Fortschritt informieren? – Olga

-1

Wenn es nur diese 2 Typen sind, denke ich, dass Sie Ihr Problem damit umgehen können.

Object.prototype.toString = function(obj){ 

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

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

    return obj.toString(); 

} 
+2

Wie ich in meiner Frage gesagt habe, weiß ich, dass ich die Art, wie ich den Typ bekomme, ändern könnte, aber ich würde es lieber nicht tun müssen. Außerdem wird Ihr Code nicht funktionieren, weil Sie die native Methode verloren haben, die anstelle des Aufrufs 'obj.toString()' benötigt würde. Beachten Sie auch, dass "typeof" ein Operator und keine Funktion ist und "object" für "null" zurückgibt (das ist die Eigenart, die ich in meiner Frage erwähnt habe). –

+0

Bitte korrigieren Sie Ihre Antwort 'typeof null === 'object'' – Olga

0

Ich gebe zu, ich bin ein bisschen hier zu erreichen, aber die MDN article on Object.toString() erwähnt:

in JavaScript Start 1.8.5 toString() auf null zurückkehrt genannt [Objekt Null], und undefiniert returns [Objekt Undefined], wie in der 5. Ausgabe von ECMAScript und einem nachfolgenden Errata definiert. Siehe Using toString to detect object type.

Der verknüpfte Abschnitt beschreibt dann das Konstrukt Object.prototype.toString(null), das Sie verwenden. So scheint es in der Lage zu sein, null und undefined sinnvoll zu stringifizieren ist eine neue (-ish) Ergänzung/Korrektur zu Javascript, das die PhantomJS-Engine (Apples JavaScriptCore, bei wer weiß welche Version) noch nicht implementiert. In Safari 6 funktioniert dies jedoch korrekt. Es kann also sinnvoll sein, dies als Fehler zu melden und nach ES5-Kompatibilität zu fragen.

Verwandte Themen