Перейти к содержимому
Теория · Объекты · урок 3 из 13

Обход объекта

Когда подпись строки известна заранее, анкету читают точечно: prices.apple. Но иногда нужно пройти по всей анкете, а какие в ней подписи, заранее неизвестно. Например, чтобы сложить все цены в объекте prices.

Представьте, что анкету переписывают в таблицу: отдельно столбец подписей, отдельно столбец ответов. С таблицей уже можно работать как со списком. Для этого есть три функции, которые превращают объект в массив:

JavaScript
const prices = { apple: 3, pear: 5, plum: 2 };

console.log(Object.keys(prices)); // [ 'apple', 'pear', 'plum' ]
console.log(Object.values(prices)); // [ 3, 5, 2 ]
console.log(Object.entries(prices)); // [ [ 'apple', 3 ], [ 'pear', 5 ], [ 'plum', 2 ] ]

Ключи, значения и пары

Каждая функция возвращает свой массив:

  • Object.keys — массив ключей;
  • Object.values — массив значений;
  • Object.entries — массив пар.

Каждая пара — массив из двух элементов: ключ с индексом 0 и значение с индексом 1. В анкете это полоска бумаги, на которой подпись и ответ записаны рядом.

Во всех трёх массивах свойства идут в одном порядке. Поэтому keys[i] и values[i] относятся к одному свойству.

Object.entries удобен, когда нужны и ключ, и значение сразу. У пары entry ключ — entry[0], значение — entry[1].

Обход в цикле

Результат — обычный массив, поэтому с ним работают все методы массивов. Свойства length у объекта нет, и число его свойств узнают через Object.keys(prices).length:

JavaScript
const total = Object.values(prices).reduce((sum, p) => sum + p, 0);
console.log(total, Object.keys(prices).length); // 10 3

for (const key in prices) {
    console.log(key, prices[key]);
}
// apple 3
// pear 5
// plum 2

Давайте разберём пример по строкам:

  1. Object.values(prices) даёт массив [3, 5, 2], и reduce складывает его в 10.
  2. Object.keys(prices).length — длина массива ключей, то есть число свойств: 3.
  3. Цикл for…in проходит по ключам объекта: на каждом шаге в key лежит очередной ключ.
  4. Тело цикла печатает ключ и его значение, по строке на свойство.

По массиву цикл for…in даёт индексы, а по объекту — ключи. Значение читают через квадратные скобки: prices[key]. Запись prices.key здесь не подойдёт — она ищет свойство с буквальным именем key.

Порядок ключей

Ключ, записанный числом, становится строкой: в объекте { 2: "x" } ключ — "2". Ключ, похожий на целое неотрицательное число, называют целочисленным ключом.

Все способы обхода выдают ключи в одном порядке:

  1. сначала целочисленные ключи, по возрастанию как числа;
  2. затем остальные — в порядке добавления.
JavaScript
const o = { b: 1, 10: 1, a: 1, 2: 1 };

console.log(Object.keys(o).join(" ")); // 2 10 b a

Разберём, откуда взялся такой порядок:

  • ключ 10 стоит после 2, хотя как строка "10" меньше "2": целочисленные ключи сравниваются как числа;
  • b остаётся перед a, потому что его добавили раньше;
  • ключи "01" и "-1" целочисленными не считаются и идут вместе с остальными строками.

Здесь анкета перестаёт помогать. На бумаге строки идут так, как их записали, а объект переставляет целочисленные ключи вперёд. Если важен порядок добавления, не полагайтесь на него в объекте с целочисленными ключами: храните элементы в массиве.

Порядок ключей часто проверяют на собеседовании: дают объект со смешанными ключами и спрашивают, что напечатает Object.keys. Ответ складывается из двух правил выше.

Частая ошибка

Объект перебрали циклом for…of, как массив:

JavaScript
const prices = { apple: 3, pear: 5 };

for (const p of prices) { // ✗
    console.log(p);
}
TEXT
TypeError: prices is not iterable

for…of работает с массивами и строками, а обычный объект он перебирать не умеет. Слово iterable в сообщении значит «перебираемый»: for…of принимает только перебираемые значения.

Передайте ему массив: for (const p of Object.values(prices)) даёт значения, а for (const entry of Object.entries(prices)) — пары.

Главное

  • Object.keys, Object.values и Object.entries превращают объект в массив ключей, значений или пар.
  • Своего length у объекта нет: число свойств — Object.keys(obj).length.
  • for…in по объекту даёт ключи, а значение читают через obj[key].
  • Целочисленные ключи идут первыми по возрастанию, остальные — в порядке добавления.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом