Skip to main content

Чому typeof null дорівнює object

typeof null повертає "object", і це історична помилка JavaScript, а не логічна властивість мови. Вона живе в мові з 1995 року і залишена навмисно, щоб не зламати мільйони старих скриптів.

Теорія

TL;DR

  • typeof null === "object", результат саме такий і змінювати його ніхто не буде.
  • Причина в ранньому 32-бітному представленні значень, де тег об'єкта був 000, а null складався з самих нулів.
  • Це офіційно визнана «відома помилка», задокументована в ECMAScript.
  • Не виправили через зворотну сумісність: правки поламали б величезну кількість робочого коду.
  • Для перевірки на null використовуйте value === null, а не typeof.
  • Щоб відрізнити справжній об'єкт від null, потрібна складена умова.

Швидкий приклад

javascript
typeof null === "object"; // true

Результат: "object".

Історична причина

У ранніх версіях JS значення зберігалися у вигляді 32-бітних тегованих даних:

  • перші 3 біти вказували на тип даних;
  • решта 29 біт зберігали саме значення.

Для об'єктів використовувався типовий тег 000, тобто три нулі на початку 32-бітного значення. А в null усе значення складалося з нулів (0x00).

Тому під час перевірки typeof null рушій бачив перші три біти 000 і робив висновок, що це об'єкт. Так і з'явилося:

javascript
typeof null; // "object"

Чому це не виправили

Тому що мільйони старих скриптів по всьому інтернету можуть залежати від цієї поведінки. Виправлення призвело б до масових поломок.

Тому специфікація ECMAScript залишила це як «відому помилку», але офіційно задокументувала її.

Як правильно перевіряти null

Через цей баг не можна використовувати лише typeof для перевірки на null.

Неправильно:

javascript
if (typeof value === 'object') { // тут value цілком може бути null! }

Правильно:

javascript
if (value === null) { console.log('This is null'); }

Або якщо треба відрізнити null від інших об'єктів:

javascript
if (typeof value === 'object' && value !== null) { console.log('This is an object, but not null'); }

Приклад для наочності

javascript
console.log(typeof null); // "object" console.log(typeof {}); // "object" console.log(typeof []); // "object" console.log(null === {}); // false console.log(null === undefined); // false

Усі три (null, {}, []) повертають "object", але це різні типи даних.

Підсумкова таблиця

ПеревіркаРезультатПояснення
typeof null"object"Історична помилка реалізації
null === nulltrueСаме значення дорівнює собі
typeof undefined"undefined"Очікувана поведінка
typeof {}"object"Справжній об'єкт
typeof []"object"Масив це підтип об'єкта

Типові помилки

  • Перевіряти об'єкт через typeof value === 'object' без додаткової умови. null пройде таку перевірку, і наступне звертання до властивості кине TypeError.
  • Вважати, що null це об'єкт. null це окремий примітивний тип; "object" віддає лише оператор typeof.
  • Плутати null і undefined. null === undefined дає false, хоча null == undefined дає true через приведення типів.
  • Сподіватися, що баг колись виправлять. Він зафіксований у специфікації назавжди, пишіть код з розрахунку на нього.
  • Використовувати typeof value === 'null'. Такого рядка typeof не повертає ніколи, умова завжди буде хибною.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.