2013-01-08 22 views
10

Po uruchomieniu następujący kod w przeglądarce lub w node.js, można uzyskać oczekiwane efekty wymienione w komentarzach:Dlaczego null i undefined są typu DOMWindow?

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

Po uruchomieniu tego kodu w PhantomJS jednak wyjście jest [object DOMWindow] w oba przypadki.

Wydaje się to dziwne, ponieważ undefined i null są typami natywnymi. Operator typeof wydaje się działać jak ma to miejsce w innych środowiskach (w tym typeof null === "object" dziwactwo), więc wydaje się, że PhantomJS ma przynajmniej mieć pojęcie typu nieokreślonego:

typeof undefined; // "undefined" 

Twierdzi ona również, że Object.prototype.toString zawiera rodzimy kod, który może wskazywać, że Phantom nie robi nic, aby zmodyfikować implementację (nie wiem, czy tak jest, czy nie - nie znalazłem nic przydatnego w źródle):

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

Dlaczego więc PhantomJS nie używa (lub przynajmniej nie eksponuje) prawidłowego [[Class]] wartości właściwości dla null i undefined i czy istnieje sposób, że to zmienię? Wiem, że mógłbym użyć innej metody do określenia typu, ale wolałbym nie.

+6

To brzmi jak błąd. – SLaks

+0

@SLaks - Tak, to była moja pierwsza myśl, ale to nie jest tak, że jest to nietypowy lub rzadko spotykany kod ... Bardzo wątpię, że jestem pierwszym, który natknął się na to, a jednak nie znalazłem żadnego odniesienia do w dowolnym miejscu w narzędziu do śledzenia problemów. –

+0

Z ciekawości: na jakie problemy próbujesz rozwiązać lub na które warunki wpływa to zachowanie? –

Odpowiedz

7

Jest to połączenie dwóch rzeczy. Skrypt jest wykonywany w ramach strony internetowej, a zatem globalny obiekt jest obiektem window, o czym świadczą:

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

Ponadto, istnieje problem z tą wersją realizacji JavaScript, który fałszuje łańcuch prototypów obiektu pod powyższy warunek.

Prawdopodobnie zostanie to naprawione w przyszłości.

+0

Dzięki za udzielenie oficjalnej odpowiedzi :) Zauważyłem, że obiekt globalny był' window' i zakładał, że ma to coś wspólnego, ale przeszukując źródło zarówno Phantom, jak i JSC były nużące i nigdzie mnie nie dostarczyły. –

+1

Czy jest jakiś problem w PhantomJS lub JSC? –

+0

Każdy dobry błąd staje się jeszcze lepszy z wiekiem - czy możesz zaktualizować postępy? – Olga

-1

Jeśli chodzi tylko o te 2 typy, myślę, że możesz po prostu otoczyć swój problem tym.

Object.prototype.toString = function(obj){ 

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

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

    return obj.toString(); 

} 
+2

Jak już powiedziałem w moim pytaniu, wiem, że mogłem zmienić sposób, w jaki dostaję typ, ale wolałbym nie. Dodatkowo twój kod nie zadziała, ponieważ utraciłeś natywną metodę, która byłaby potrzebna zamiast wywołania 'obj.toString()'. Zauważ też, że 'typeof' jest operatorem, a nie funkcją, i zwraca" object "dla' null' (to jest dziwactwo, o którym wspominam w moim pytaniu). –

+0

Proszę poprawić odpowiedź 'typeof null === 'object'' – Olga

0

Muszę przyznać, ja rodzaj dotarcia tutaj, ale MDN article on Object.toString() wspomina:

Zaczynając w JavaScript 1.8.5 toString() wezwał zerowych zysków [object Null], a niezdefiniowane powraca [object Niezdefiniowane], zdefiniowane w 5. Wydaniu ECMAScript i późniejszej Errata. Zobacz Using toString to detect object type.

Połączona sekcja opisuje konstrukcję Object.prototype.toString(null), której używasz. Wygląda więc na to, że można sensownie stringify null i undefined jest nowym (-ja) dodatkiem/korektą do Javascriptu, że silnik PhantomJS (AppleCooking JavaScriptCore, kto wie która wersja) jeszcze nie implementuje. To powiedziawszy, działa to poprawnie w Safari 6, więc warto byłoby zgłosić to jako błąd, prosząc o zgodność z ES5.

Powiązane problemy