Dlaczego typeof ma wartość „obiekt”?

241

Czytam rozdział 4 „Profesjonalny Javascript dla programistów stron internetowych” i mówi mi, że pięć typów prymitywów to: niezdefiniowany, null, boolean, liczba i łańcuch.

Jeśli nulljest prymitywne, dlaczego typeof(null)powraca "object"?

Czy nie oznacza nullto, że jest przekazywany przez referencję (zakładam, że wszystkie obiekty są przekazywane przez referencję), a zatem czyniąc to NIE prymitywnym?

thetrystero
źródło
50
Odpowiedź: Ponieważ specyfikacja tak mówi. Jest to ogólnie uważane za błąd.
SLaks,
5
Uwaga: typeof jest operatorem, a nie funkcją (a tak naprawdę można pominąć nawiasy wokół tego, co następuje po nim), więc nie ma sensu mówić o przekazywaniu przez odniesienie tutaj. Książka „JavaScript: dobre części” faktycznie wspomina fakt, że typeof null === „obiekt” w sekcji A.6 dodatku A zatytułowanym „Okropne części”.
John Sonderson
5
Myślę, że chciałbym przeczytać „Okropne części” hah
austinheiman
1
ogromny błąd, niezgłębiony! :)
Alexander Mills
2
Czego więc powinniśmy używać zamiast typeof, aby sprawdzić, jaką wartość ma zmienna? Chciałbym wiedzieć, co to jest pomiędzy (logiczna, ciąg, liczba, tablica, obiekt, funkcja, symbol, null, niezdefiniowany, NaN)
Costa

Odpowiedzi:

219

Ze strony MDN na temat zachowania typeofoperatora :

null

// To trwa od początku JavaScript
typeof null === „obiekt”;

W pierwszej implementacji JavaScript wartości JavaScript były reprezentowane jako znacznik typu i wartość. Tag typu dla obiektów wynosił 0. nullbył reprezentowany jako wskaźnik NULL (0x00 na większości platform). W związku z tym null miał 0 jako znacznik typu, stąd typeofzwracana jest wartość „object” . ( odniesienie )

Zaproponowano poprawkę dla ECMAScript (poprzez opt-in), ale została odrzucona . Spowodowałoby to typeof null === 'null'.

Deepak Ingole
źródło
137
Szkoda, że ​​ta zmiana przynajmniej nie przeszła w tryb ścisły…
Ingo Bürk
Ludzie korzystają z tego dziwactwa i wiele kodu będzie musiało zostać zmienionych, jeśli nie zostanie odrzucone, tak sądzę
Cold Cerberus
Ma to większy sens dla niewielu żywych ludzi, którzy chcą to zmienić swój kod, niż reszta programistów przez resztę czasu musi się go nauczyć. To, że dana osoba jeszcze nie istnieje, niekoniecznie oznacza, że ​​nie ma znaczenia, oznacza tylko, że jest bezbronna.
Seph Reed
i tak nie ma sensu, dlaczego ludzie używają tego jako kontroli zerowej. To nie ma intuicyjnego sensu, więc dlaczego mieliby z niego korzystać? Teraz zmiany nie można dodać z powodu złego kodowania.
Emobe,
69

Jeśli nulljest prymitywne, dlaczego typeof(null)powraca "object"?

Ponieważ specyfikacja tak mówi .

11.4.3typeof Operator

Produkcja UnaryExpression : typeof UnaryExpression jest oceniany w następujący sposób:

  1. Niech val będzie wynikiem oceny UnaryExpression .
  2. Jeśli Type ( val ) to Reference , to
       a. Jeśli IsUnresolvableReference ( val ) ma wartość true , zwróć „ undefined”.
       b. Niech val będzie GetValue ( val ).
  3. Zwraca ciąg określony przez typ ( val ) zgodnie z tabelą 20.

wprowadź opis zdjęcia tutaj

Matt Ball
źródło
@peter nie typeofmówi ci nic o tym, czy możesz wywoływać metody na czymś.
Matt Ball
2
O ile mi wiadomo, możesz wywoływać metody na czymkolwiek innym niż nulli undefined.
Matt Ball
4
@ Peter nie można wywoływać metod na prymitywie łańcucha, ale na szczęście prymitywy łańcucha (oraz prymitywy liczb i operacje logiczne) są domyślnie i automatycznie „automatycznie zapakowane” w opakowaniach String, Number i Boolean, gdy używasz jednego z prymitywów z właściwością operator referencyjny ( .lub [ ]).
Pointy
28

Jak już wspomniano, specyfikacja tak mówi. Ponieważ jednak implementacja JavaScriptu poprzedza napisanie specyfikacji ECMAScript, a specyfikacja uważała, aby nie poprawić błędów początkowej implementacji, nadal istnieje uzasadnione pytanie, dlaczego zostało to zrobione w ten sposób. Douglas Crockford nazywa to błędem . Kiro Risk uważa, że ​​to trochę ma sens :

Powodem tego jest to null, że w przeciwieństwie do tego undefined, było (i nadal jest) często używane tam, gdzie pojawiają się obiekty. Innymi słowy, nulljest często używany do oznaczenia pustego odwołania do obiektu. Kiedy Brendan Eich stworzył JavaScript, postępował zgodnie z tym samym paradygmatem i miało sens (prawdopodobnie) zwrócenie „obiektu”. W rzeczywistości specyfikacja ECMAScript definiuje nulljako pierwotną wartość, która reprezentuje celowy brak jakiejkolwiek wartości obiektu (ECMA-262, 11.4.11).

chryss
źródło
3
Ponieważ nie mogę teraz znaleźć filmu, opublikuję go tylko dla ciekawskich ludzi i bez żadnego odniesienia: Crockford wyjaśnił, w jaki sposób zerowa wartość przy rozwiązywaniu typu null wskazuje na zerowy element indeksowany w tablicy typów, więc było to jasne błąd, który faceci Microsoftu
rozeszli się
6

Z książki YDKJS

Jest to od dawna błąd w JS, ale prawdopodobnie nigdy nie zostanie naprawiony. Zbyt dużo kodu w sieci zależy od błędu, a zatem jego poprawienie spowodowałoby o wiele więcej błędów!

Faisal Ashfaq
źródło
1
nie ufaj, że wszystko jest napisane w książce. Naprawdę uwielbiam tę książkę, jednak nie mogę uznać tego za błąd, ponieważ specyfikacja ECMA dla JavaScript stwierdza, że ​​typ null musi być obiektem.
andreasonny83
4

Jeśli nulljest prymitywne, dlaczego typeof(null)zwraca „ object”?

w skrócie: jest to błąd w ECMAScript, a typ powinien być null

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

Praca w
źródło
1
Nigdzie w twojej referencji nie stwierdzono, że jest to błąd.
user2867288,
1
I nigdzie w specyfikacji nie jest powiedziane, że typeof powinien zwracać cokolwiek innego niż „niezdefiniowany”, „obiekt”, „boolean”, „liczba”, „ciąg”, „funkcja” i „symbol” (ECMAScript 2015)
Brad Kent
1

W JavaScript null to „nic”. To ma być coś, co nie istnieje. Niestety, w JavaScript, typ danych null jest obiektem. Możesz uznać za błąd w JavaScript, że typeof null jest obiektem. Powinno być zerowe.

Farzana Khan
źródło
0

W JavaScript typof null to „obiekt”, co niepoprawnie sugeruje, że null jest obiektem. Jest to błąd, którego niestety nie można naprawić, ponieważ spowodowałby uszkodzenie istniejącego kodu.

Slim Coder
źródło