Объекты
Объект — коллекция именованных свойств (пар ключ-значение), основной способ структурирования данных в JavaScript.
Зачем нужно
Объекты — фундаментальная структура данных JS. Почти всё в JS — объект: массивы, функции, Date, RegExp. Понимание объектов необходимо для работы с любым API и фреймворком.
Где используется
- Хранение структурированных данных
- Конфигурации и настройки
- Ответы API (JSON)
- DOM-элементы
- Модули и пространства имён
Предпосылки
Создание объектов
// 1. Литерал объекта (основной способ)
const user = {
name: 'Алиса',
age: 25,
isActive: true
};
// 2. new Object (не рекомендуется)
const obj = new Object();
obj.name = 'Боб';
// 3. Object.create
const proto = { greet { return `Привет, ${this.name}`; } };
const person = Object.create(proto);
person.name = 'Чарли';
console.log(person.greet); // "Привет, Чарли"
// 4. Конструктор / Класс
class User {
constructor(name) {
this.name = name;
}
}
const u = new User('Дана');
Свойства: чтение, запись, удаление
const user = { name: 'Алиса', age: 25 };
// Чтение
console.log(user.name); // 'Алиса' (точечная нотация)
console.log(user['age']); // 25 (скобочная нотация)
// Запись
user.email = 'alice@mail.com'; // добавление
user.age = 26; // изменение
// Динамический ключ — только через
const key = 'name';
console.log(user[key]); // 'Алиса'
// Удаление
delete user.email;
console.log(user.email); // undefined
// Проверка существования свойства
console.log('name' in user); // true
console.log(user.hasOwnProperty('name')); // true
console.log(Object.hasOwn(user, 'name')); // true (ES2022)
Вычисляемые свойства
const field = 'color';
const value = 'red';
const config = {
[field]: value, // { color: 'red' }
[`${field}Dark`]: 'darkred', // { colorDark: 'darkred' }
['get' + 'Name'] { return 'Алиса'; } // метод getName
};
console.log(config.color); // 'red'
console.log(config.colorDark); // 'darkred'
console.log(config.getName); // 'Алиса'
Сокращённая запись
const name = 'Алиса';
const age = 25;
// Shorthand properties
const user = { name, age };
// Эквивалент: { name: name, age: age }
// Shorthand methods
const calculator = {
add(a, b) { return a + b; }, // вместо add: function(a, b) {...}
subtract(a, b) { return a - b; }
};
Перебор объектов
const user = { name: 'Алиса', age: 25, city: 'Москва' };
// for...in (включая унаследованные свойства)
for (const key in user) {
if (user.hasOwnProperty(key)) {
console.log(`${key}: ${user[key]}`);
}
}
// Object.keys() — массив ключей
Object.keys(user); // ['name', 'age', 'city']
// Object.values() — массив значений
Object.values(user); // ['Алиса', 25, 'Москва']
// Object.entries() — массив пар [ключ, значение]
Object.entries(user);
// [['name', 'Алиса'], ['age', 25], ['city', 'Москва']]
// Удобный перебор
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`);
}
// Object.fromEntries — обратное преобразование
const entries = [['a', 1], ['b', 2]];
Object.fromEntries(entries); // { a: 1, b: 2 }
Деструктуризация
const user = { name: 'Алиса', age: 25, city: 'Москва' };
// Базовая
const { name, age } = user;
console.log(name); // 'Алиса'
// С переименованием
const { name: userName, age: userAge } = user;
console.log(userName); // 'Алиса'
// Со значением по умолчанию
const { name, country = 'Россия' } = user;
console.log(country); // 'Россия'
// Вложенная деструктуризация
const response = {
data: {
users: [{ id: 1, name: 'Алиса' }]
}
};
const { data: { users: [firstUser] } } = response;
console.log(firstUser.name); // 'Алиса'
// Rest-свойства
const { name, ...rest } = user;
console.log(rest); // { age: 25, city: 'Москва' }
Spread оператор
const defaults = { theme: 'light', lang: 'ru', fontSize: 14 };
const userPrefs = { theme: 'dark', fontSize: 16 };
// Слияние (последний побеждает)
const config = { ...defaults, ...userPrefs };
// { theme: 'dark', lang: 'ru', fontSize: 16 }
// Поверхностная копия
const copy = { ...user };
copy.name = 'Боб';
console.log(user.name); // 'Алиса' — оригинал не изменился
// Добавление свойств
const enhanced = { ...user, role: 'admin', updatedAt: Date.now() };
Полезные методы Object
// Object.assign — копирование свойств
const target = { a: 1 };
Object.assign(target, { b: 2 }, { c: 3 });
console.log(target); // { a: 1, b: 2, c: 3 }
// Object.freeze — полная заморозка
const frozen = Object.freeze({ x: 1, y: 2 });
frozen.x = 10; // игнорируется (strict mode — ошибка)
frozen.z = 3; // игнорируется
console.log(frozen.x); // 1
// Object.keys()/values/entries
Object.keys({ a: 1, b: 2 }); // ['a', 'b']
Object.values({ a: 1, b: 2 }); // [1, 2]
Object.entries({ a: 1, b: 2 }); // [['a', 1], ['b', 2]]
// Object.hasOwn (ES2022) — замена hasOwnProperty
Object.hasOwn({ a: 1 }, 'a'); // true
Object.hasOwn({ a: 1 }, 'b'); // false
// Object.groupBy (ES2024)
const people = [
{ name: 'Алиса', age: 25 },
{ name: 'Боб', age: 30 },
{ name: 'Чарли', age: 25 }
];
const grouped = Object.groupBy(people, p => p.age);
// { 25: [{name:'Алиса',...}, {name:'Чарли',...}], 30: [{name:'Боб',...}] }
Optional chaining с объектами
const user = {
name: 'Алиса',
address: {
city: 'Москва'
}
};
// Без optional chaining
const zip = user.address && user.address.zip; // undefined
// С optional chaining
const zip2 = user.address?.zip; // undefined
const street = user.location?.street; // undefined (нет ошибки)
// Вызов метода
const result = user.getName?.; // undefined если метода нет
Частые ошибки
1. Мутация через ссылку
const original = { a: 1, nested: { b: 2 } };
const copy = { ...original };
copy.nested.b = 999;
console.log(original.nested.b); // 999 — spread делает ПОВЕРХНОСТНУЮ копию!
// Решение: structuredClone для глубокой копии
const deepCopy = structuredClone(original);
2. for...in перебирает унаследованные свойства
// Используй Object.keys() или проверку hasOwnProperty
for (const key of Object.keys(obj)) {
// Только собственные свойства
}
3. Порядок ключей
// Числовые ключи сортируются первыми
const obj = { b: 2, 1: 'one', a: 1, 2: 'two' };
Object.keys(obj); // ['1', '2', 'b', 'a']
Практика
- Создай объект
studentсо свойствами и методомintroduce - Напиши функцию
merge(obj1, obj2)без использования spread - Напиши функцию
pick(obj, keys)— возвращает объект только с указанными ключами - Глубоко скопируй объект с вложенными массивами и объектами