Warum ist typeof null "Objekt"?

241

Ich lese Kapitel 4 "Professionelles Javascript für Webentwickler" und erfahre, dass die fünf Arten von Grundelementen undefiniert, null, boolesch, Zahl und Zeichenfolge sind.

Wenn nulles ein Primitiv ist, warum kehrt es typeof(null)zurück "object"?

Würde das nicht bedeuten, dass dies nullals Referenz übergeben wird (ich gehe hier davon aus, dass alle Objekte als Referenz übergeben werden), was es NICHT zu einem Grundelement macht?

Thetrystero
quelle
50
Antwort: Weil die Spezifikation dies sagt. Dies wird allgemein als Fehler angesehen.
SLaks
5
Beachten Sie, dass typeof ein Operator ist, keine Funktion (und tatsächlich können Sie die Klammern um das, was danach kommt, weglassen). Daher ist es nicht sinnvoll, hier über das Übergeben von Referenzen zu sprechen. Das Buch "JavaScript: The Good Parts" erwähnt tatsächlich die Tatsache, dass typeof null === 'object' in Abschnitt A.6 von Anhang A mit dem Titel 'Awful Parts'.
John Sonderson
5
Ich denke, ich würde gerne 'Awful Parts' lesen hah
austinheiman
1
großer Fehler, unergründlich! :)
Alexander Mills
2
Was sollten wir also anstelle von typeof verwenden, um zu überprüfen, welche Art von Wert eine Variable enthält? Ich würde gerne wissen, was es zwischen (Boolescher Wert, Zeichenfolge, Zahl, Array, Objekt, Funktion, Symbol, Null, undefiniert, NaN)
Costa

Antworten:

219

Auf der MDN-Seite zum Verhalten des typeofBedieners :

null

// Dies steht seit dem Beginn von JavaScript
typeof null === 'object';

In der ersten Implementierung von JavaScript wurden JavaScript-Werte als Typ-Tag und Wert dargestellt. Das Typ-Tag für Objekte war 0. Es nullwurde als NULL-Zeiger dargestellt (0x00 auf den meisten Plattformen). Folglich hatte null 0 als Typ-Tag, daher der typeofRückgabewert "Objekt" . ( Referenz )

Für ECMAScript wurde ein Fix vorgeschlagen (über ein Opt-In), der jedoch abgelehnt wurde . Es hätte dazu geführt typeof null === 'null'.

Deepak Ingole
quelle
137
Es ist eine Schande, dass diese Änderung es nicht zumindest in den strengen Modus geschafft hat…
Ingo Bürk
Die Leute haben die Eigenart ausgenutzt, und viele Codes müssen geändert werden, wenn dies nicht abgelehnt wurde, denke ich
Cold Cerberus
Für die wenigen lebenden Menschen, die möchten, dass dies ihren Code ändert, ist es sinnvoller, als für den Rest der Entwickler, ihn für den Rest der Zeit lernen zu müssen. Nur weil eine Person noch nicht existiert, heißt das nicht unbedingt, dass sie keine Rolle spielt, sondern nur, dass sie wehrlos ist.
Seph Reed
macht keinen Sinn, warum die Leute dies sowieso als Null-Check verwenden würden. Es macht keinen intuitiven Sinn. Warum sollten sie es verwenden? Jetzt kann die Änderung wegen schlechter Codierung nicht hinzugefügt werden.
Emobe
69

Wenn nulles ein Primitiv ist, warum kehrt es typeof(null)zurück "object"?

Weil die Spezifikation es sagt .

11.4.3 Der typeofBediener

Die Produktion UnaryExpression : typeof UnaryExpression wird wie folgt ausgewertet:

  1. Sei val das Ergebnis der Auswertung von UnaryExpression .
  2. Wenn Typ ( Wert ) Referenz ist , dann
       a. Wenn IsUnresolvableReference ( val ) true ist , geben Sie " undefined" zurück.
       b. Lassen Val sein GetValue ( val ).
  3. Geben Sie eine Zeichenfolge zurück, die durch Typ ( Wert ) gemäß Tabelle 20 bestimmt wird.

Geben Sie hier die Bildbeschreibung ein

Matt Ball
quelle
@peter typeofsagt Ihnen nichts darüber, ob Sie Methoden für etwas aufrufen können oder nicht.
Matt Ball
2
Meines Wissens können Sie Methoden für alles andere als nullund aufrufen undefined.
Matt Ball
4
@peter Sie können keine Methoden für ein Zeichenfolgenprimitiv aufrufen, aber dankenswerterweise werden Zeichenfolgenprimitive (und Zahlenprimitive und Boolesche Grundelemente) in Zeichenfolgen-, Zahlen- und Booleschen Wrappern implizit und automatisch "automatisch verpackt", wenn Sie eines der Grundelemente mit einer Eigenschaft verwenden Referenzoperator ( .oder [ ]).
Pointy
28

Wie bereits erwähnt, heißt es in der Spezifikation. Da die Implementierung von JavaScript jedoch vor dem Schreiben der ECMAScript-Spezifikation erfolgte und die Spezifikation darauf geachtet hat, die Schwächen der ursprünglichen Implementierung nicht zu korrigieren, gibt es immer noch eine berechtigte Frage, warum dies überhaupt so gemacht wurde. Douglas Crockford nennt es einen Fehler . Kiro Risk findet das irgendwie sinnvoll :

Der Grund dafür ist, dass nullim Gegensatz dazu undefinedhäufig dort verwendet wurde (und wird), wo Objekte erscheinen. Mit anderen Worten, nullwird häufig verwendet, um einen leeren Verweis auf ein Objekt zu kennzeichnen. Als Brendan Eich JavaScript erstellte, folgte er demselben Paradigma, und es war (wohl) sinnvoll, "Objekt" zurückzugeben. Tatsächlich definiert die ECMAScript-Spezifikation nullals den primitiven Wert, der das absichtliche Fehlen eines Objektwerts darstellt (ECMA-262, 11.4.11).

Chrys
quelle
3
Da ich das Video jetzt nicht finden kann, werde ich es nur für neugierige Leute und ohne Referenz veröffentlichen: Crockford erklärte, wie ein Nullwert beim Auflösen des Nulltyps auf das nullindizierte Element im Typarray zeigte, also war dies klar Entwicklung eines Fehlers, den die Microsoft-Leute versehentlich beim Dekompilieren und Neukompilieren von JS für ihren Browser verbreitet haben
Áxel Costas Pena
6

Aus dem Buch YDKJS

Dies ist ein langjähriger Fehler in JS, der jedoch wahrscheinlich nie behoben wird. Zu viel Code im Web hängt vom Fehler ab und daher würde das Beheben des Fehlers viel mehr Fehler verursachen!

Faisal Ashfaq
quelle
1
Vertraue nicht, dass alles in einem Buch geschrieben ist. Ich liebe dieses Buch wirklich, aber ich kann es nicht als Fehler betrachten, da die ECMA-Spezifikation für JavaScript besagt, dass der Typ Null ein Objekt sein muss.
andreasonny83
4

Wenn nulles sich um ein Primitiv handelt, warum wird typeof(null)" object" zurückgegeben?

Kurz gesagt: Es ist ein Fehler in ECMAScript, und der Typ sollte sein null

Referenz: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null

Job in
quelle
1
Nirgends in Ihrer Referenz heißt es, dass es sich um einen Fehler handelt.
user2867288
1
Und nirgends in der Spezifikation heißt es, dass typeof etwas anderes als "undefiniert", "Objekt", "Boolescher Wert", "Zahl", "Zeichenfolge", "Funktion" und "Symbol" zurückgeben sollte (ECMAScript 2015)
Brad Kent
1

In JavaScript ist null "nichts". Es soll etwas sein, das es nicht gibt. Leider ist in JavaScript der Datentyp null ein Objekt. Sie können es als Fehler in JavaScript betrachten, dass der Typ null ein Objekt ist. Es sollte null sein.

Farzana Khan
quelle
0

In JavaScript ist der Typ null 'Objekt', was fälschlicherweise darauf hindeutet, dass null ein Objekt ist. Dies ist ein Fehler, der leider nicht behoben werden kann, da er den vorhandenen Code beschädigen würde.

Schlanker Codierer
quelle