Объекты в JavaScript: деструктуризация, spread/rest, Object.keys/values/entries
Работа с объектами в JavaScript — создание, деструктуризация, spread-оператор, методы Object.keys, Object.values, Object.entries, Object.assign, shallow copy.
Создание объектов
Объект — коллекция пар «ключ-значение». Ключ — строка или Symbol, значение — что угодно:
const user = {
name: 'Анна',
age: 25,
isAdmin: false,
hobbies: ['чтение', 'плавание'],
address: {
city: 'Москва',
street: 'Тверская',
},
}
Ключи можно использовать как вычисляемые:
const field = 'name'
const obj = { [field]: 'Анна' } // { name: 'Анна' }
Если имя ключа совпадает с переменной — короткая запись:
const name = 'Анна'
const age = 25
const user = { name, age } // { name: 'Анна', age: 25 }
Доступ к свойствам
Два способа — через точку и через квадратные скобки:
user.name // 'Анна'
user['age'] // 25
const key = 'name'
user[key] // 'Ання'
// Для ключей с нестандартными символами — только скобки
const config = { 'api-key': 'abc123' }
config['api-key'] // 'abc123'
Добавление и изменение свойств
user.email = 'anna@mail.ru' // добавить
user.age = 26 // изменить
user['phone'] = '+7-999-123-4567' // через скобки
delete user.isAdmin // удалить
Проверка наличия свойства
'name' in user // true
'phone' in user // false
user.address !== undefined // true — но если значение может быть undefined, лучше 'in'
user.hasOwnProperty('name') // true
Деструктуризация объекта
Извлечение свойств в отдельные переменные:
const user = { name: 'Анна', age: 25, city: 'Москва' }
const { name, age } = user
console.log(name) // 'Ання'
console.log(age) // 25
Переименование переменной при деструктуризации:
const { name: userName, age: userAge } = user
console.log(userName) // 'Ання'
Значение по умолчанию, если свойства нет:
const { name, role = 'user' } = user
console.log(role) // 'user' — потому что role не было в объекте
Переименование + значение по умолчанию:
const { name: userName = 'Гость' } = { name: 'Анна' }
Вложенная деструктуризация:
const user = {
name: 'Анна',
address: { city: 'Москва', street: 'Тверская' },
}
const { address: { city, street } } = user
console.log(city) // 'Москва'
Деструктуризация в параметрах функции:
function greet({ name, age }) {
console.log(`Привет, ${name}! Тебе ${age} лет.`)
}
greet({ name: 'Анна', age: 25 })
Spread-оператор (...)
Копирование объекта (поверхностное)
const original = { a: 1, b: 2 }
const copy = { ...original }
copy.a = 99
console.log(original.a) // 1 — не изменилось
Объединение объектов
const defaults = { theme: 'light', lang: 'ru', perPage: 10 }
const userPrefs = { theme: 'dark', perPage: 20 }
const settings = { ...defaults, ...userPrefs }
// { theme: 'dark', lang: 'ru', perPage: 20 }
Порядок важен — поздние свойства перезаписывают ранние.
Добавление свойств
const user = { name: 'Анна', age: 25 }
const withRole = { ...user, role: 'admin' }
// { name: 'Анна', age: 25, role: 'admin' }
Удаление свойства (без мутации)
const { isAdmin, ...rest } = { name: 'Анна', age: 25, isAdmin: true }
console.log(rest) // { name: 'Анна', age: 25 }
Поверхностная копия — ловушка
Spread копирует только первый уровень. Вложенные объекты — по ссылке:
const original = { name: 'Анна', address: { city: 'Москва' } }
const copy = { ...original }
copy.address.city = 'Санкт-Петербург'
console.log(original.address.city) // 'Санкт-Петербург' — изменилось!
Для глубокой копии:
const deepCopy = structuredClone(original)
Object.keys / values / entries
const user = { name: 'Анна', age: 25, city: 'Москва' }
Object.keys(user) // ['name', 'age', 'city'] — массив ключей
Object.values(user) // ['Анна', 25, 'Москва'] — массив значений
Object.entries(user) // [['name', 'Анна'], ['age', 25], ['city', 'Москва']]
Перебор через entries:
for (const [key, value] of Object.entries(user)) {
console.log(`${key}: ${value}`)
}
// name: Анна
// age: 25
// city: Москва
Object.assign
Копирует свойства из одного или нескольких объектов в целевой:
const target = { a: 1 }
const source = { b: 2, c: 3 }
Object.assign(target, source)
console.log(target) // { a: 1, b: 2, c: 3 }
// Для создания копии — передайте пустой объект первым аргументом
const copy = Object.assign({}, target)
Object.assign мутирует первый аргумент. Spread-оператор предпочтительнее — он не мутирует.
Object.freeze и Object.seal
// freeze — полностью заморозить объект
const config = Object.freeze({ apiUrl: '/api', timeout: 5000 })
config.timeout = 3000 // молча не сработает (или TypeError в строгом режиме)
config.newField = true // молча не сработает
// seal — нельзя добавлять/удалять, но можно менять существующие
const user = Object.seal({ name: 'Анна', age: 25 })
user.age = 26 // OK
user.city = 'Мск' // не добавится
delete user.name // не удалится
Обе функции — поверхностные. Вложенные объекты не защищены.
Методы объекта
Короткий синтаксис метода:
const user = {
name: 'Анна',
greet() {
return `Привет, я ${this.name}`
},
}
user.greet() // 'Привет, я Анна'
Object.hasOwn
Современная замена hasOwnProperty:
const user = { name: 'Анна' }
Object.hasOwn(user, 'name') // true
Object.hasOwn(user, 'age') // false
Object.hasOwn(user, 'toString') // false — это из прототипа
Частые задачи
Преобразовать массив объектов в объект по ключу
const users = [
{ id: 1, name: 'Анна' },
{ id: 2, name: 'Иван' },
]
const byId = Object.fromEntries(users.map(u => [u.id, u]))
// { 1: { id: 1, name: 'Анна' }, 2: { id: 2, name: 'Иван' } }
Объединить два объекта, отдав приоритет второму
const merged = { ...defaults, ...overrides }
Глубокое сравнение двух объектов
function deepEqual(a, b) {
if (a === b) return true
if (typeof a !== 'object' || typeof b !== 'object') return false
if (a === null || b === null) return false
const keysA = Object.keys(a)
const keysB = Object.keys(b)
if (keysA.length !== keysB.length) return false
return keysA.every(key => deepEqual(a[key], b[key]))
}
Итог
- Деструктуризация — удобный способ извлечь свойства:
const { name, age } = user - Spread
{ ...obj }— поверхностная копия,structuredClone()— глубокая Object.keys/values/entries— для перебора и трансформацииObject.freeze— если объект менять не должны- Все методы копирования поверхностные — вложенные объекты копируются по ссылке