2016-11-16 8 views
6

ich tat etwas Forschung auf typeof Bedienungs JavaScript und über die folgende Seltsamkeit gestolpert:Warum ist document.all definiert, aber typeof document.all gibt "undefined" zurück?

Ausnahmen

All aktueller Browser ein Nicht-Standard Nicht definiert mit Typ document.all Objekt Host aus.

Obwohl die Spezifikation benutzerdefinierte Typen-Tags für nicht standardmäßige exotische Objekte zulässt, müssen diese Typen-Tags sich von den vordefinierten unterscheiden. Der Fall document.all mit dem Typenschild 'undefined' muss als außergewöhnlicher Verstoß gegen die Regeln eingestuft werden.

(Source)

Ich habe folgendes in meinem Browser, um es zu testen:

console.log("typeof: " + typeof document.all); 
console.log("toString: " + document.all); 

Es ergab:

typeof: undefined 
toString: [object HTMLAllCollection] 

Warum ist document.all so? Da document.all ein Objekt ist (in meinem Browser definiert), sollte typeof nicht "object" zurückgegeben werden, nicht "undefined"?

+2

sein Vielleicht kann dies Ihre Frage beantworten: http: // Stackoverflow. com/questions/10350142/why-is-Dokument-all-falsy Bearbeiten: Dieser gibt weitere Details: http://StackOverflow.com/Questions/20880324/Document-all-is-not-working-in-firefox) – Seblor

+0

Für Legacy-Kram würdest du es versuchen Niemals benutzen. –

+0

@Seblor keiner von denen sagen, warum 'typeof document.all ===" undefined "' obwohl. –

Antwort

6

Werfen Sie einen Blick auf dieses von Html Spec

Das all Attribut muss ein HTMLAllCollection am Document Knoten verwurzelten zurückkehren, deren Filter alle Elemente übereinstimmt.

Das zurückgegebene Objekt für all mehrere ungewöhnliche Verhalten hat:

  1. Der User-Agent muss handeln, als ob die ToBoolean abstrakte Operation in JavaScript false zurückgibt, wenn angesichts der Aufgabe für alle zurückgegeben.

  2. Der User-Agent, als ob die abstrakten Gleichheit Vergleichsalgorithmus handeln muss, wenn das Objekt gegeben zurück für all, kehrt true wenn im Vergleich zu den undefined und null Werten. (Vergleiche die strikte Gleichheit Vergleich Algorithmus, und abstrakte Gleichheit Vergleiche zu anderen Werten wie Strings oder Objekte sind unberührt.)

  3. Der User-Agent so handeln müssen, dass der typeof-Operator in JavaScript gibt die Zeichenfolge " undefiniert ", wenn es auf das zurückgegebene Objekt für all angewendet wird.

Der dritte Fall ist bei Ihnen.

Der Grund hierfür ist die Kompatibilität mit dem Code für alten Browser entwickelt, wie es in einer Notiz in der Beschreibung erläuterte:

Diese Verletzung durch den Wunsch nach Kompatibilität mit zwei Klassen von Legacy-Inhalten motiviert ist: ein, verwendet das Vorhandensein von document.all als eine Möglichkeit, Legacy-Benutzeragenten zu erkennen, und eines, das nur diese Legacy-Benutzeragenten unterstützt und das document.all-Objekt verwendet, ohne zuerst auf seine Anwesenheit zu testen.

Ich hoffe, es wird für Sie Sinn machen.

+0

zurückgeben. Sagt nicht, _why_ es hat diese Eigenschaften, obwohl. –

+0

@StephenLeppik Die Standards erklären selten die Gründe für Entscheidungen. – zerkms

+4

@StephenLeppik Hast du den Link verfolgt? Es gibt eine große grüne ** Note **, die erklärt, warum. – Barmar

0

Eine Abhilfe Update:

document.all !== undefined; 
>> true /*otherwise*/ false 

Seit https://html.spec.whatwg.org/ erfordert, dass ...

Der User-Agent, als ob die abstrakten Gleichheit Vergleichsalgorithmus handeln muss, wenn man sich das Objekt für alle zurückgekehrt, gibt im Vergleich zu den Werten für undefined und null den Wert true zurück.

aber seit ...

(Vergleiche den strikten Gleichheit Vergleich Algorithmus, und abstrakte Gleichheit Vergleiche zu anderen Werten wie Strings oder Objekte sind unberührt.)

die Verwendung von Statischer Typ Vergleich Operator (zB: === |! ==) ist vollkommen sicher zu prüfen, ob das HTMLAllCollection Objekt im aktuellen UA-Client verwendbar und/oder vorhanden ist.

Die Dynamisch Vergleich Operator wird jedoch weiterhin eine falsche Abwesenheit zurückzukehren, wie durch die Spezifikation erforderlich.

document.all != undefined; 
>> false /*otherwise*/ false 

Eine Abhilfe (ältere)

"all" in document; 
>> true /*otherwise*/ false 

Ein aufwendiger Ansatz, wenn sie mit Dritten Code tun würde

delete document.all && "all" in document 
>> true /*otherwise*/ false 
Verwandte Themen