Comments 8
TL;DR версия для ленивых:
Раньше:
это баг
В современном прочтении:
это баг. а это ссылка на мой уютненький
Не "это баг" а "это легаси"
Статья, в оригинале, действительно писался не для Хабра. Мотивацией к написанию послужило то, что я постоянно слышу от разработчиков, что typeof
смотрит на первые три бита значения переменной и по ним определяет тип. Так было много лет назад, но давно уже ушло в историю. И V8, и SpiderMonkey сейчас построены совершенно по другому, и я посчитал нужным этот вопрос освятить. На Хабр пост попал только потому, что мне показалось, он здесь уместен и будет интересен сообществу. Все ссылки в тексте статьи, которые, в изначальном варианте, ведут на оригинальные публикации (не на Хабре) были заменены на кросс-статьи на Хабре, кроме стандартной, для моих публикаций, подписи в конце статьи.
Печально, что вы увидели в посте только рекламу и никакой полезной информации.
Да божечки мои...
Case-переход в "современных" движках — это всего лишь FizzBuzz, реализованный сотней if/else для, соответственно, первой сотни последовательности. Там, где раньше был алгоритм (пусть и кривой), этот алгоритм нынче всего лишь захардкодили прямым джампом в зависимости от конкретного значения. На забагованном результате, как это и написано в статье, это никак не отразилось. Мой первый комментарий остаётся полностью в силе.
Алгоритм хоть и отличается от оригинального кода Mocha, хорошо иллюстрирует суть ошибки. В нем просто нет проверки на тип
Null
. Вместо этого, в случаеval === "null"
, алгоритм попадает в веткуelse if (JSVAL_IS_OBJECT(v))
и возвращаетJSTYPE_OBJECT
Вот она проверка на null
:
if (obj &&
И никакая это не ошибка. null
- это во всех языках нулевой указатель на объект. Так же как NaN
- это буквально не число имеющее тип числа. И так же как ""
- это отсутствие текста, имеющее тип строки.
Зачем в спецификации значение null
вынесли в отдельный unit тип - хороший вопрос. Смысла в этом мало. Разве что были планы ввести конструктор Null
, и дать возможность вызывать некоторые методы на null
, как это сделали с числами, строками и прочими примитивными типами.
Это сделали для того, чтобы можно было отличить указатель на языковой конструкт null/nil/None от неинициализированного указателя на объект любого другого типа. При этом null в JS и None в питоне не просто так сделали синглтон-объектами: это и проверять проще (сравнил адрес и готово), и следить за ссылками легче.
В питоне, например, NoneType не экспортирует никаких свойств и методов у экземпляров, то есть, обособление типа не обусловлено особыми интерфейсами.
Вообще вполне логично когда тип null это базовый объект, а не какой-то производный. Поскольку любой производный от объекта тип может быть null.
Почему typeof null === «object» в современном прочтении