
Кирилл Мыльников
Frontend разработчик
Всем привет, я — Кирилл, frontend разработчик компании Usetech.
Сегодня поговорим о глубоком и поверхностном клонировании объекта, посмотрим различные примеры и способы как это можно реализовать, а также разберём отличия, плюсы и минусы данного подхода, уделим внимание новому встроенному методу глубокого клонирования — structuredClone.
Глубокое клонирование:
structuredClone(obj)
lodash.cloneDeep(obj)
JSON.parse(JSON.stringify(obj))
Полифил cloneDeep(obj)
Поверхностное клонирование:
Оператор Spread
Object.assign()
Object.create()
Знали ли вы, что теперь в JavaScript есть встроенный способ делать глубокие копии объекта?
Итак, мы говорим про structuredClone — это функция встроенная в среду JavaScript:
const person = {
name: "Ivan",
date: new Date(123),
friends: ["John"]
}
// клон объекта
const copiedPerson = structuredClone(person)Обратите внимание, мы скопировали не только объект, но ещё и вложенный массив, и даже объект Date.
Как видите, всё работает так, как ожидалось.
copiedPerson.friends // ["John"]
copiedPerson.date // Date: Wed Dec 31 1969 16:00:00
copiedPerson.friends === person.friends // falseМетод structuredClone может выполнять следующие задачи:
Клонировать бесконечно вложенные объекты и массивы;
Клонировать циклические ссылки;
Клонировать различные типы JS, такие, как
Date,Error,RegExp,ArrayBuffer,Blob,File,ImageDataи другие;Передача любых передаваемых объектов.
Даже такой безумный пример сработал, как мы и хотели.
const obj = {
set: new Set([1123, 36, 3, 4, 4]),
map: new Map([[133, 2222]]),
regex: /foo/,
deep: { array: [ new File(someBlobData, 'test.txt') ] },
error: new Error('Error!')
}
obj.circular = obj
// ✅ Все хорошо, клонировали весь объект.
const clonedObj = structuredClone(obj)Почему бы просто взять и не развернуть объект?
Тут важно понимать, какое клонирование мы хотим: глубокое или поверхностное. Если нам нужно сделать поверхностное клонирование, то есть копию, которая не копирует вложенные объекты или массивы, то тогда можно обойтись Spread оператором.
Пример:
const obj = {
title: "Builder.io Conf",
}
// ✅ нет проблем, нет вложенных массивов и объектов
const shallowCopy = {...obj}Есть иной способ поверхностного клонирования:
const shallowCopy = Object.assign({}, obj);
const shallowCopy = Object.create(obj);Рассмотрим пример, когда у нас вложенные значения — это объект.
const personObj = {
title: "Hello world",
date: new Date(123),
friends: ["John"]
}
const shallowCopy = {...calendarEvent}
// 