Avatar ·

Как узнать длину (количество свойств) объекта в JavaScript?

Всем привет! Я только начал изучать JavaScript и столкнулся с непонятной ситуацией. У массивов есть свойство `.length`, которое показывает количество элементов. Но когда я пытаюсь применить то же самое к объекту, получаю `undefined`. Вот пример: ```javascript const person = { name: 'Иван', age: 30, city: 'Москва' }; console.log(person.length); // undefined ``` У меня есть объект с тремя свойствами. Как мне получить число 3? Я пробовал использовать `Object.keys()`, но не уверен, что это правильный путь. Подскажите, пожалуйста, как в JS узнать "длину" объекта? И почему у объектов нет встроенного свойства `.length`, как у массивов? Заранее спасибо! <<>>

Почему у объектов нет свойства length?

В JavaScript массивы и объекты — это разные структуры данных. Массивы упорядочены и имеют числовые индексы, поэтому у них есть встроенное свойство length. Объекты же — это неупорядоченные коллекции пар "ключ-значение", и их "длина" не является встроенной характеристикой, так как количество свойств может меняться динамически, и у объекта нет предопределённой длины.

Основной способ: Object.keys()

Самый простой и стандартный метод — использовать Object.keys(). Он возвращает массив всех собственных (не унаследованных) перечисляемых строковых ключей объекта. Затем вы просто берёте длину этого массива:

const person = {
  name: 'Иван',
  age: 30,
  city: 'Москва'
};

const keys = Object.keys(person);
console.log(keys);        // ["name", "age", "city"]
console.log(keys.length); // 3

Этот метод работает во всех современных браузерах и Node.js. Он учитывает только собственные свойства (не из прототипа) и только перечисляемые (что обычно и нужно).

Альтернативные методы

  • Object.values() — возвращает массив значений. Длина этого массива будет равна количеству свойств:
  • console.log(Object.values(person).length); // 3
  • Object.entries() — возвращает массив пар [ключ, значение]. Длина также показывает количество свойств:
  • console.log(Object.entries(person).length); // 3
  • Цикл for...in (с проверкой hasOwnProperty) — старый способ, но его стоит знать:
  • let count = 0;
    for (let key in person) {
      if (person.hasOwnProperty(key)) {
        count++;
      }
    }
    console.log(count); // 3

    Важно использовать hasOwnProperty, чтобы не учитывать свойства из цепочки прототипов.

Что насчёт символов?

Все методы выше (Object.keys, for...in) не учитывают свойства, ключами которых являются символы (Symbol). Если у вас есть такие свойства, используйте Object.getOwnPropertySymbols():

const sym = Symbol('id');
const obj = { a: 1 };
obj[sym] = 'secret';

const allKeys = [
  ...Object.keys(obj),
  ...Object.getOwnPropertySymbols(obj)
];
console.log(allKeys.length); // 2 (ключа 'a' и символ)

Краткий итог

  • Для обычных объектов используйте Object.keys(obj).length — это лучший современный способ.
  • Если нужно учесть символы — комбинируйте Object.keys() и Object.getOwnPropertySymbols().
  • Не пытайтесь добавить свойство length в прототип Object — это сломает код других разработчиков и нарушит стандарты.
<<>>

Дополнительный подход: Reflect.ownKeys()

Если вам нужно получить все собственные ключи объекта, включая как строковые, так и символьные, и при этом не важно, перечисляемые они или нет, используйте Reflect.ownKeys():

const person = {
  name: 'Иван',
  age: 30
};
const sym = Symbol('id');
person[sym] = 'secret';

// Object.keys() не увидит символ
console.log(Object.keys(person).length); // 2

// Reflect.ownKeys() увидит всё
console.log(Reflect.ownKeys(person).length); // 3

Этот метод возвращает массив всех собственных ключей объекта (строки и символы, перечисляемые и неперечисляемые). Он появился в ES6 и поддерживается всеми современными средами.

Важно: Reflect.ownKeys() не включает унаследованные свойства, что обычно и требуется. Если вам нужно посчитать только перечисляемые строковые ключи (как в 99% случаев), используйте Object.keys().