Как перебрать свойства объекта в JavaScript: от новичка до профи
Каждый разработчик, который пишет на JavaScript, рано или поздно сталкивается с задачей: «А как мне пройтись по всем свойствам объекта?». Если вы привыкли работать с массивами, где есть for, forEach и map, то объекты могут показаться непослушными. Но не спешите расстраиваться! В этой статье мы разберем все способы итерации по объекту в JavaScript — от классического for...in до современных Object.keys(), Object.values() и Object.entries().
Мы не просто покажем синтаксис. Мы разберем, какой метод выбрать для конкретной задачи, какие подводные камни существуют, и как не наступить на грабли с наследованными свойствами. Поехали!
Что такое объект в JavaScript и почему его нужно перебирать?
Объект — это коллекция пар «ключ: значение». В отличие от массива, где элементы упорядочены по индексу, в объекте порядок свойств не гарантируется (хотя современные движки стараются его сохранить).
Представьте, что у вас есть объект с данными пользователя:
const user = {
name: 'Анна',
age: 28,
city: 'Москва',
isAdmin: false
};
Вам нужно вывести все данные на экран, отправить их на сервер или просто что-то посчитать. Без итерации придется писать user.name, user.age и т.д. — это негибко и не масштабируется. А если у объекта 50 свойств? Тут-то и пригодятся методы итерации.
Способ №1: Классический for...in
Самый старый и прямолинейный способ перебрать свойства объекта — использовать цикл for...in. Он был создан специально для объектов.
const user = {
name: 'Анна',
age: 28,
city: 'Москва'
};
for (let key in user) {
console.log(key + ': ' + user[key]);
}
// Вывод:
// name: Анна
// age: 28
// city: Москва
Здесь key — это имя свойства (строковое значение), а user[key] — его значение.
Важно! for...in перебирает не только собственные свойства объекта, но и те, что унаследованы через цепочку прототипов. Это может привести к неожиданным результатам, особенно если вы расширяли прототипы встроенных объектов (чего делать не стоит, но мало ли).
Чтобы избежать этого, используйте метод hasOwnProperty:
for (let key in user) {
if (user.hasOwnProperty(key)) {
console.log(key + ': ' + user[key]);
}
}
Современная альтернатива — Object.hasOwn() (ES2022):
for (let key in user) {
if (Object.hasOwn(user, key)) {
console.log(key + ': ' + user[key]);
}
}
Когда использовать for...in? Когда вам нужны имена свойств (ключи) и вы уверены, что не столкнетесь с наследованными свойствами. Либо когда вы работаете с простыми объектами, созданными литералом {}.
Способ №2: Object.keys() — получаем массив ключей
Метод Object.keys() возвращает массив собственных (не унаследованных) перечисляемых свойств объекта. Это самый популярный и безопасный способ итерации на сегодняшний день.
const user = {
name: 'Анна',
age: 28,
city: 'Москва'
};
const keys = Object.keys(user);
console.log(keys); // ['name', 'age', 'city']
// Теперь можно использовать forEach или for...of
keys.forEach(key => {
console.log(key + ': ' + user[key]);
});
Преимущество: вы получаете обычный массив, с которым можно делать всё, что угодно — фильтровать, маппить, сортировать.
Пример с фильтрацией:
const filteredKeys = Object.keys(user).filter(key => key !== 'isAdmin');
filteredKeys.forEach(key => console.log(user[key]));
Когда использовать Object.keys()? Практически всегда, когда нужно перебрать объект и получить ключи. Это стандартный выбор для 80% задач.
Способ №3: Object.values() — только значения
Если вам не нужны ключи, а только значения свойств — используйте Object.values(). Он возвращает массив значений.
const user = {
name: 'Анна',
age: 28,
city: 'Москва'
};
const values = Object.values(user);
console.log(values); // ['Анна', 28, 'Москва']
values.forEach(value => {
console.log('Значение: ' + value);
});
Этот метод незаменим, когда вы хотите, например, просуммировать числовые значения объекта или просто показать все данные без указания названий полей.
Пример подсчёта:
const scores = {
math: 90,
physics: 85,
english: 78
};
const total = Object.values(scores).reduce((sum, score) => sum + score, 0);
console.log('Сумма баллов: ' + total); // 253
Когда использовать Object.values()? Когда ключи не важны, а нужны только значения для вычислений или отображения.
Способ №4: Object.entries() — ключи и значения вместе
Самый мощный и современный метод — Object.entries(). Он возвращает массив массивов, где каждый внутренний массив — это пара [ключ, значение].
const user = {
name: 'Анна',
age: 28,
city: 'Москва'
};
const entries = Object.entries(user);
console.log(entries);
// [ ['name', 'Анна'], ['age', 28], ['city', 'Москва'] ]
// Итерируем с деструктуризацией
entries.forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
Особенно удобно использовать Object.entries() вместе с Object.fromEntries() для трансформации объектов:
// Делаем все значения строками
const stringified = Object.fromEntries(
Object.entries(user).map(([key, value]) => [key, String(value)])
);
console.log(stringified); // { name: 'Анна', age: '28', city: 'Москва' }
Или для создания нового объекта с отфильтрованными полями:
const filtered = Object.fromEntries(
Object.entries(user).filter(([key]) => key !== 'age')
);
console.log(filtered); // { name: 'Анна', city: 'Москва' }
Когда использовать Object.entries()? Когда вам одновременно нужны и ключи, и значения, особенно для преобразования объекта в другой формат (например, в Map, для создания URL-параметров и т.д.).
Сравнение методов: что выбрать?
Давайте сведём всё в удобную таблицу:
- for...in — перебирает все перечисляемые свойства, включая унаследованные. Требует
hasOwnProperty. Подходит для простых