Чому typeof null "об'єкт"?


241

Я читаю розділ 4 "Професійний Javascript для веб-розробників", і це говорить мені про те, що п'ять типів примітивів: невизначені, нульові, булеві, число та рядки.

Якщо nullпримітив, чому typeof(null)повертається "object"?

Хіба це не означає, що nullце передається посиланням (я припускаю, що тут усі об'єкти передаються за посиланням), отже, це робить НЕ примітивним?


50
Відповідь: Тому що специфікація так говорить. Зазвичай це вважається помилкою.
SLaks

5
Зауважте, typeof - це оператор, а не функція (і насправді ви можете опускати дужки навколо того, що відбувається після нього), тому тут не має сенсу говорити про проходження посилання. Книга "JavaScript: хороші частини" фактично згадує той факт, що typeof null === 'object "у розділі A.6 додатка A під назвою" Awful Parts ".
Джон Сондерсон

5
Думаю, я хотів би прочитати "Жахливі частини" так
австрійхайм

1
величезна помилка, незбагненна! :)
Олександр Міллс

2
Отже, що нам слід використовувати замість typeof, щоб перевірити тип значення, яке має змінна? Я хотів би знати, що це між (булева, рядок, число, масив, об’єкт, функція, символ, null, undefined, NaN)
Коста,

Відповіді:


219

На сторінці MDN про поведінку typeofоператора :

null

// Це стоїть з початку JavaScript
typeof null === 'об’єкт';

У першій реалізації JavaScript значення JavaScript були представлені як тег типу та значення. Тег типу для об'єктів становив 0. nullбув представлений у вигляді покажчика NULL (0x00 на більшості платформ). Отже, null мав 0 як тип тегу, звідси typeofповернення значення "об'єкт" . ( довідник )

Для ECMAScript було запропоновано виправлення (через відмову), але його було відхилено . Це призвело б до typeof null === 'null'.


137
Прикро, що ця зміна принаймні не перейшла в суворий режим…
Ingo Bürk

Люди скористалися химерністю, і багато кодів там доведеться змінити, якщо це не буде відхилено, я думаю
Cold Cerberus

Мало сенсу для небагатьох живих людей, які хочуть, щоб цей код змінився, ніж решти розробників, що залишилися, щоб вивчити його. Просто тому, що людина ще не існує, це не означає, що вони не мають значення, це просто означає, що вони беззахисні.
Seph Reed

не має сенсу, чому люди все-таки використовуватимуть це як нульову перевірку. Це не має інтуїтивного сенсу, тож навіщо їм користуватися? Тепер зміни не можуть бути додані через неправильне кодування.
Emobe

69

Якщо nullпримітив, чому typeof(null)повертається "object"?

Бо специфікація так говорить .

11.4.3typeof Оператор

Виробництво UnaryExpression : typeof UnaryExpression оцінюється наступним чином:

  1. Нехай val є результатом оцінки UnaryExpression .
  2. Якщо Type ( val ) є посиланням , то
       a. Якщо IsUnresolvableReference ( val ) вірно , поверніть " undefined".
       б. Нехай val буде GetValue ( val ).
  3. Поверніть рядок, визначену Type ( val ) відповідно до таблиці 20.

введіть тут опис зображення


@peter typeofнічого не говорить про те, чи можна викликати методи на чомусь.
Метт Бал

2
Наскільки мені відомо, ви можете закликати методи на що-небудь крім nullі undefined.
Метт Бал

4
@peter ви не можете викликати способи на строковому примітиві, але, на щастя, рядкові примітиви (а також примітивні числа та булеві примітиви) неявно та автоматично "автоматично коробляються" в обгортках String, Number та Boolean, коли ви використовуєте один із примітивів із властивістю опорний оператор ( .або [ ]).
Pointy

28

Як було зазначено, спецпризначення говорить так. Але оскільки реалізація JavaScript передує написанню специфікації ECMAScript, і специфікація обережно не виправляє файли первинної реалізації, все ще існує правомірне питання про те, чому це робилося в першу чергу. Дуглас Крокфорд називає це помилкою . Кіро Ризик вважає, що це свого роду має сенс :

Причина цього полягає в тому null , , на відміну від undefined, часто використовувався там, де з'являються об'єкти. Іншими словами, nullчасто використовується для позначення порожнього посилання на об'єкт. Коли Брендан Ейх створив JavaScript, він дотримувався тієї ж парадигми, і було сенс (мабуть) повернути "об'єкт". Фактично, специфікація ECMAScript визначає nullяк примітивне значення, яке представляє навмисну ​​відсутність будь-якого об'єктного значення (ECMA-262, 11.4.11).


3
Оскільки я зараз не можу знайти це відео, я опублікую це лише для допитливих людей і без будь-якої посилання: Крокфорд пояснив, як нульове значення при вирішенні типу null вказувало на нульовий індексований елемент масиву типів, тому це було зрозуміло розробка помилки, яку хлопці Microsoft випадково поширювали під час декомпіляції та перекомпіляції JS для свого браузера
Аксель Костас Пена

6

З книги YDKJS

Це давня помилка в JS, але вона, ймовірно, ніколи не буде виправлена. Занадто багато коду в Інтернеті покладається на помилку, і, таким чином, виправлення може спричинити набагато більше помилок!


1
не вірте, все написано в книзі. Мені дуже подобається ця книга, однак я не можу вважати це помилкою, оскільки специфікація ECMA для JavaScript зазначає, що тип null повинен бути об'єктом.
andreasonny83

4

Якщо nullпримітив, чому typeof(null)повертається " object"?

коротше: це помилка в ECMAScript, і тип повинен бути null

довідка: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null


1
Ніде у вашому посиланні не зазначено, що це помилка.
користувач2867288

1
І ніде в специфікації не сказано, що typeof повинен повертати нічого, окрім "невизначеного", "об'єкта", "булевого", "числа", "рядка", "функції" та "символу" (ECMAScript 2015)
Бред Кент,

1

У JavaScript null - "нічого". Це, мабуть, щось, чого не існує. На жаль, в JavaScript тип даних null є об'єктом. Ви можете вважати помилкою в JavaScript, що typeof null є об'єктом. Він повинен бути недійсним.


0

У JavaScript typeof null - це «об’єкт», що неправильно говорить про те, що null є об’єктом. Це помилка, яку, на жаль, неможливо виправити, оскільки вона порушить існуючий код.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.