Объекты: основы
Объект — коллекция пар «ключ-значение». Ключи — строки или символы.
Создание
const user = {
name: 'Алиса',
age: 25,
email: 'alice@example.com',
};
Через конструктор:
const empty = new Object();
const fromNull = Object.create(null); // без прототипа
Доступ
user.name; // 'Алиса'
user['name']; // 'Алиса'
Через переменную:
const key = 'name';
user[key]; // 'Алиса'
Добавление и изменение
user.age = 26;
user['email'] = 'new@example.com';
user.city = 'Москва';
Удаление
const { email, ...rest } = user; // без email, user не меняется
delete user.email; // мутирует
Современный подход — деструктуризация со rest.
Проверка свойства
'name' in user; // true
Object.hasOwn(user, 'name'); // ES2022, только собственное
user.hasOwnProperty('name'); // старый способ
in проверяет и унаследованные, Object.hasOwn — только собственные.
Ключи, значения, записи
Object.keys(user); // ['name', 'age', 'email']
Object.values(user); // ['Алиса', 25, '...']
Object.entries(user); // [['name', 'Алиса'], ...]
Порядок:
- Числовые ключи по возрастанию
- Строковые в порядке добавления
- Символы в порядке добавления
Перебор
for (const [key, value] of Object.entries(user)) {
console.log(key, value);
}
Методы объекта
const calculator = {
value: 0,
add(n) {
this.value += n;
return this;
},
sub(n) {
this.value -= n;
return this;
},
};
calculator.add(5).sub(2);
Методы — функции как свойства.
Сокращённые свойства
const name = 'Алиса';
const age = 25;
const user = { name, age };
// { name: 'Алиса', age: 25 }
Вычисляемые ключи
const key = 'name';
const user = { [key]: 'Алиса' };
// { name: 'Алиса' }
const prefix = 'user_';
const data = {
[`${prefix}name`]: 'Алиса',
};
// { user_name: 'Алиса' }
Вложенные
const data = {
user: {
profile: {
name: 'Алиса',
},
},
};
data.user.profile.name;
data.user?.profile?.name; // безопасный доступ
Опциональная цепочка
user?.address?.city; // undefined, если нет
user?.getName?.(); // вызов, если функция есть
user?.['dynamic-key']; // доступ по ключу
Слияние
Object.assign({}, a, b);
{ ...a, ...b };
Конфликт ключей — последний выигрывает.
Глубокое слияние:
function deepMerge(target, source) {
const result = { ...target };
for (const [key, value] of Object.entries(source)) {
if (value && typeof value === 'object' && !Array.isArray(value)) {
result[key] = deepMerge(result[key] ?? {}, value);
} else {
result[key] = value;
}
}
return result;
}
Заморозка
Object.freeze(user);
user.name = 'Боб'; // не сработает в strict
Только верхний уровень. Для глубокой:
function deepFreeze(obj) {
Object.freeze(obj);
Object.values(obj).forEach((v) => {
if (v && typeof v === 'object') deepFreeze(v);
});
return obj;
}
Проверка на пустоту
Object.keys(user).length === 0;
Итоги
- Ключи — строки или символы
- Доступ через точку или скобки
inиObject.hasOwnдля проверкиObject.keys,values,entries- Spread для слияния
Object.freezeдля иммутабельности