JS: Объекты

Теория: Клонирование и копирование

Клонирование объектов — еще одна часто встречающаяся операция в разработке, особенно во фронтенде. При клонировании создается копия исходного объекта — то есть новый объект, наполненный теми же данными.

В JavaScript клонирование можно эмулировать с помощью Object.assign(). Для этого нужно первым параметром передать пустой объект, а вторым — тот, который нужно клонировать:

const user = { name: 'Tirion', email: 'support@hexlet.io', age: 44 }

// Данные из user копируются во вновь созданный объект
const copyOfUser = Object.assign({}, user)

user === copyOfUser // false

В результате получаются два разных объекта с одним и тем же содержимым. Объекты разные, поэтому изменения в одном не меняют данные в другом.

Клонирование также выполняют с помощью функции clone() библиотеки lodash. Результат выполнения этой функции идентичен примерам выше, но благодаря своему имени, она лучше выражает смысл операции:

import _ from 'lodash'

const user = { name: 'Tirion', email: 'support@hexlet.io', age: 44 }
const copyOfUser = _.clone(user)

Клонирование способами выше не затрагивает вложенные объекты. Они оказываются в новом объекте по ссылке из старого:

const user = { company: { name: 'Hexlet' } }
const copyOfUser = Object.assign({}, user)
// Это тот же объект
user.company === copyOfUser.company // true

user.company.createdAt = 2012
console.log(copyOfUser.company.createdAt) // 2012

Такое клонирование называется поверхностным (shallow copying). Очень важно запомнить, что именно это имеют в виду в JavaScript, когда употребляют термин «клонирование». Поверхностное клонирование подходит для многих ситуаций, но иногда его недостаточно. В таких случаях нужно использовать полное или глубокое клонирование (deep copying).

В JavaScript есть встроенный метод structuredClone(), c помощью которого можно выполнить глубокое копирование объектов:

const user = { company: { name: 'Hexlet' } }
const copyOfUser = structuredClone(user)

user.company === copyOfUser.company // false

Библиотека lodash также предоставляет готовую функцию cloneDeep(). Она была распространенным решением проблемы глубокого копирования, пока не появился метод structuredClone().

У полного клонирования есть один серьезный недостаток. Если мы работаем с большим объектом со сложной структурой, то полное клонирование может сильно влиять на производительность. Это одна из причин, почему такое клонирование не выполняется по умолчанию.

Рекомендуемые программы