Обход объекта
Когда подпись строки известна заранее, анкету читают точечно: prices.apple. Но иногда нужно пройти по всей анкете, а какие в ней подписи, заранее неизвестно. Например, чтобы сложить все цены в объекте prices.
Представьте, что анкету переписывают в таблицу: отдельно столбец подписей, отдельно столбец ответов. С таблицей уже можно работать как со списком. Для этого есть три функции, которые превращают объект в массив:
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:
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Давайте разберём пример по строкам:
Object.values(prices)даёт массив[3, 5, 2], иreduceскладывает его в10.Object.keys(prices).length— длина массива ключей, то есть число свойств:3.- Цикл
for…inпроходит по ключам объекта: на каждом шаге вkeyлежит очередной ключ. - Тело цикла печатает ключ и его значение, по строке на свойство.
По массиву цикл for…in даёт индексы, а по объекту — ключи. Значение читают через квадратные скобки: prices[key]. Запись prices.key здесь не подойдёт — она ищет свойство с буквальным именем key.
Порядок ключей
Ключ, записанный числом, становится строкой: в объекте { 2: "x" } ключ — "2". Ключ, похожий на целое неотрицательное число, называют целочисленным ключом.
Все способы обхода выдают ключи в одном порядке:
- сначала целочисленные ключи, по возрастанию как числа;
- затем остальные — в порядке добавления.
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, как массив:
const prices = { apple: 3, pear: 5 };
for (const p of prices) { // ✗
console.log(p);
}TypeError: prices is not iterablefor…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 и подпишись на канал — откроются все уроки.