← Назад к вопросам

Почему вызов typeof для массива возвращает объект?

2.0 Middle🔥 171 комментариев
#JavaScript Core#TypeScript

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Почему typeof массива возвращает 'object'

Краткий ответ: Потому что в языке JavaScript массив является подтипом объекта, и оператор typeof реализован так, чтобы различать примитивные типы и ссылочный тип 'object', не вдаваясь в детали его специализации.

Архитектурное решение в JavaScript

Исторически и технически в JavaScript существует всего 7 примитивных типов (string, number, bigint, boolean, symbol, undefined, null) и один ссылочный тип – Object. Все остальные сложные структуры данных, включая массивы, функции, даты, регулярные выражения и даже сами объекты, являются реализациями или частными случаями типа Object.

Массив в JS – это объект со следующими особенностями:

  • Специальная внутренняя структура для эффективного хранения элементов по индексам.
  • Автоматически обновляемое свойство length.
  • Наследование от Array.prototype, что предоставляет методы вроде push, pop, map.

Оператор typeof, появившийся на раннем этапе развития языка, не различает подтипы объектов. Его задача – быстро определить категорию значения.

console.log(typeof [1, 2, 3]); // 'object'
console.log(typeof { name: 'John' }); // 'object'
console.log(typeof null); // 'object' (известная историческая ошибка)
console.log(typeof function() {}); // 'function' (особый случай)

Как правильно определить массив?

Поскольку typeof недостаточен, для точной проверки типа массива нужно использовать другие методы:

  1. Метод Array.isArray() (рекомендованный, современный) – Специально создан для безошибочного определения массивов.

    console.log(Array.isArray([1, 2])); // true
    console.log(Array.isArray({})); // false
    console.log(Array.isArray(null)); // false
    
  2. Проверка цепочки прототипов через instanceof – Работает в большинстве случаев, но может дать сбой при работе с фреймами или разными контекстами выполнения (например, в iframe).

    console.log([] instanceof Array); // true
    console.log({} instanceof Array); // false
    
  3. "Утиная типизация" через свойства – Исторический метод, например, проверка наличия метода push и свойства length, но он ненадежен.

Причины такого дизайна языка

  • Простота и производительность typeof: Оператор работает на низком уровне, быстро возвращая строку-метку типа. Глубокая проверка потребовала бы больше ресурсов.

  • Динамическая природа JS: Массивы в JavaScript – это все же объекты, и с ними можно работать как с объектами (добавлять именованные свойства, хотя это и не рекомендуется).

    const arr = [1, 2, 3];
    arr.customProperty = 'Hello'; // Возможно, потому что это объект
    console.log(arr.customProperty); // 'Hello'
    console.log(typeof arr); // 'object'
    
  • Обратная совместимость: Изменение поведения typeof для массивов сломало бы огромное количество существующего кода.

Вывод

Возврат 'object' для массива оператором typeof – это не ошибка, а следствие фундаментальной архитектуры JavaScript, где массивы являются специализированными объектами. Для надежной проверки всегда следует использовать Array.isArray(). Это дизайнерское решение отражает философию раннего JavaScript: гибкость и простота в ущерб строгой типизации, что впоследствии было компенсировано добавлением более точных методов проверки.