WebCoder
1.08K subscribers
503 photos
31 videos
14 files
412 links
Мемы из IT и технологий
Языки и ИИ

Вопросы - @H8err
Download Telegram
16👍3
Поверхностное и глубокое клонирование объектов в JS

Если у нас стоит задача скопировать простой объект и массив, то проблем не возникает, например:

 simpleObj = {
fieldOne: 1,
fieldTwo: 2,
fieldThree: 3,
};

console.log(simpleObj);
// простой объект - {fieldOne: 1, fieldTwo: 2, fieldThree: 3,}

const simpleObjectCopy = {... simpleObj}; // используем spread для копирования простого объекта

console.log(simpleObjectCopy);
//клонированный простой объект - {fieldOne: 1, fieldTwo: 2, fieldThree: 3,}

simpleObjectCopy.fieldOne = 2; //изменим значение первого поля в копированном объекте, чтоб убедится что эти два объекта не связаны

console.log(simpleObj); // {fieldOne: 1, fieldTwo: 2, fieldThree: 3,}
console.log(simpleObjectCopy); // {fieldOne: 2, fieldTwo: 2, fieldThree: 3,}

Но что если у нас более сложный объект или массив (объект внутри которого другой объект или массив с объектами как в примере)

const foodInCart = [
{ product: 'Агава', quantity: 3},
{ product: 'Апельсин', quantity: 1 },
{ product: 'Дыня', quantity: 1 },
]

const clonedCart = [...foodInCart]

console.log(clonedCart);
// [
// { product: 'Агава', quantity: 3 },
// { product: 'Апельсин', quantity: 1 },
// { product: 'Дыня', quantity: 1 },
// ]

 = 5 // изменяем поле "количество" в объекте под индексом 1 

console.log(clonedCart)
// [
// { product: 'Агава', quantity: 3 },
// { product: 'Апельсин', quantity: 5 },
// { product: 'Дыня', quantity: 1 },
// ]

console.log(foodInCart)
// [
// { product: 'Агава', quantity: 3 },
// { product: 'Апельсин', quantity: 5 },
// { product: 'Дыня', quantity: 1 },
// ]

Как мы видим количество апельсинов поменялось сразу в двух объектах, как мы с вами знаем непримитивные типы данных, хранятся по ссылке. Так как мы произвели поверхностное копирование, то мы просто скопировали ссылки на старый объект в новый массив.

Таким образом, "разные" массивы ссылаются на одни и те же объекты в памяти:

 === clonedCart[1]); //true

JavaScript не имеет отдельных функций для глубокого копирования массивов или объектов. Существуют различные способы сделать глубокое копирование.

Можно написать функцию глубокого копирования вручную. Скорее всего ваша функция будет рекурсивной, и она будет работать только для конкретных данных — написать универсальную функцию не так-то просто.

Так же можно сериализировать копируемый объект в JSON и распарсить его :

const deepClone = JSON.parse(JSON.stringify(foodInCart))

console.log(foodInCart[1] === deepClone[1])
// false

Но данный метод не идеальный, потому что копируемые данные должны быть сериализуемыми. Если у объекта существуют методы или массив содержит функции, то копирование не сработает.

Еще один способ это воспользоваться популярной библиотекой утилит lodash
👍9
👆а вообще за копирование объектов через сериализацию в JSON и обратно могут хорошо бить по-жопе осудить более опытные коллеги
😁9👍1
😁15👎31
👍8😁7👎1
😁8👎3
👍2👎1
👍6👎1
🔥4😁31👎1
😁5
😁9👎1
👍3😁2👎1
3👎1
👎2🔥2
👎21