Почему typeof null «объект»?


242

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

Если nullпримитив, почему typeof(null)возвращается "object"?

Разве это не означает, что nullон передается по ссылке (я предполагаю, что здесь все объекты передаются по ссылке), следовательно, делая его НЕ примитивным?


50
Ответ: потому что в спецификации так сказано. Это обычно считается ошибкой.
Утром

5
Обратите внимание, что typeof - это оператор, а не функция (и на самом деле вы можете опустить круглые скобки вокруг того, что следует за ним), поэтому здесь нет смысла говорить о передаче по ссылке. В книге «JavaScript: хорошие части» фактически упоминается тот факт, что typeof null === 'object' в разделе A.6 приложения A, озаглавленном «Awful Parts».
Джон Сондерсон

5
Я думаю, что я хотел бы прочитать «Ужасные части» ха
Austinheiman

1
огромная ошибка, непостижимая! :)
Александр Миллс

2
Итак, что мы должны использовать вместо typeof, чтобы проверить тип значения, которое содержит переменная? Я хотел бы знать, что это между (булево, строка, число, массив, объект, функция, символ, ноль, неопределенный, NaN)
Коста

Ответы:


219

Со страницы MDN о поведении typeofоператора :

null

// Это стоит с начала JavaScript
typeof null === 'object';

В первой реализации JavaScript значения JavaScript были представлены как тег типа и значение. Тег типа для объектов был 0. nullбыл представлен как указатель NULL (0x00 на большинстве платформ). Следовательно, null имел 0 в качестве тега типа, поэтому typeofвозвращаемое значение «объекта» . ( ссылка )

Исправление было предложено для ECMAScript (через opt-in), но было отклонено . Это привело бы к typeof null === 'null'.


138
Жаль, что это изменение, по крайней мере, не
перешло

Люди используют эту причуду, и многие из них придется менять, если это не было отклонено, я полагаю
Холодный Цербер

Для немногих живых людей, которые хотят, чтобы это изменило свой код, имеет больше смысла, чем остальным разработчикам, чтобы они могли его изучить. Тот факт, что человек еще не существует, не обязательно означает, что он не имеет значения, он просто означает, что он беззащитен.
Сеф Рид

не имеет смысла, почему люди все равно используют это как нулевую проверку. Это не имеет интуитивного смысла, так зачем им это использовать? Теперь изменение не может быть добавлено из-за плохого кодирования.
Эмоб

69

Если nullпримитив, почему typeof(null)возвращается "object"?

Потому что в спецификации так сказано .

11.4.3typeof Оператор

Производство UnaryExpression : typeof UnaryExpression оценивается следующим образом:

  1. Пусть val будет результатом вычисления UnaryExpression .
  2. Если Тип ( val ) является Ссылкой , тогда
       a. Если IsUnresolvableReference ( val ) имеет значение true , вернуть " undefined".
       б. Пусть val будет GetValue ( val ).
  3. Возвращает строку, определенную типом ( val ) в соответствии с таблицей 20.

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


@peter typeofничего не говорит вам о том, можете ли вы вызывать методы для чего-либо.
Мэтт Болл

2
Насколько мне известно, вы можете вызывать методы на что угодно, кроме nullи undefined.
Мэтт Болл

4
@peter Вы не можете вызывать методы для строкового примитива, но, к счастью, строковые примитивы (и числовые примитивы и логические примитивы) неявно и автоматически «автоматически упаковываются» в оболочки String, Number и Boolean, когда вы используете один из примитивов со свойством оператор ссылки ( .или [ ]).
Заостренный

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
Нигде в вашей ссылке не говорится, что это ошибка.
user2867288

1
И нигде в спецификации не говорится, что typeof должен возвращать что-либо, кроме «undefined», «object», «boolean», «number», «string», «function» и «symbol» (ECMAScript 2015)
Брэд Кент,

1

В JavaScript ноль - это «ничто». Предполагается, что это нечто, чего не существует. К сожалению, в JavaScript тип данных null является объектом. Вы можете считать это ошибкой в ​​JavaScript, когда typeof null является объектом. Это должно быть нулевым.


0

В JavaScript typeof null является «объектом», что неверно предполагает, что null является объектом. Это ошибка, которая, к сожалению, не может быть исправлена, потому что она сломает существующий код.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.