Рубрики
Без рубрики

Глубокое копирование объекта в JavaScript

Быстрое и простое руководство по тому, как глубоко копировать объект в JavaScript.

Автор оригинала: Ramón Miklus.

Используя Распространение синтаксиса или Объект.assign () является стандартным способом копирования объекта в JavaScript. Обе меттологии могут быть эквивалентно использованы для Скопируйте перечислимые свойства объекта к другому объекту, с распространенным синтаксисом, являющимся корочевым из двух. Они также полезны для Объекты объединения , поскольку оба метода автоматически перезаписывают свойства в целевом объекте, которые имеют одинаковые ключевые ключи в исходном объекте.

Эти два метода были введены в Ecmascript 2015 и являются как стандартными функциями JavaScript. Они также предложены в Документация Redux , так как редукторы в Redux возвращают копию состояния вместо того, чтобы мутировать его напрямую. Однако те два метода не может быть использован, чтобы сделать глубокие копии объектов.

Проблема

Распространенный синтаксис и Объект.assign () Метод может сделать только мелкие копии объектов. Это означает, что глубоко вложенные значения внутри скопированного объекта помещают там как ссылку на исходный объект. Если мы изменим глубоко вложенное значение скопированного объекта, поэтому мы будем в конечном итоге Изменение значения в исходном объекте Отказ

Давайте возьмем в качестве примера объект ниже:

const pizzas = {
   margherita: {
      toppings: ['tomato sauce', 'mozzarella cheese'],
      prices: {
         small: '5.00',
         medium: '6.00',
         large: '7.00'
      }
   },
   prosciutto: {
      toppings: ['tomato sauce', 'mozzarella cheese', 'ham'],
      prices: { 
         small: '6.50', 
         medium: '7.50',
         large: '8.50' 
      }
   }
};

Давайте попробуем сейчас скопировать это пицца Объект выше с использованием синтаксиса распространения и измените значение одного из цен в скопированном объекте:

let pizzasCopy = {...pizzas};

// modify a value in the copy of pizzas
pizzasCopy.margherita.prices.small = '5.50';

// log the copied object to the console
console.log(pizzasCopy.margherita.prices.small); // This will log 5.50, as expected

// log the source object to the console
console.log(pizzas.margherita.prices.small); // This will also log 5.50 instead of 5.00!!

Как вы можете видеть, Цены Глубоко вложенные свойства (более одного уровня глубоко) в нашем объекте. Мы только переназнавали ценность одной из цен в скопированном Пицсихскопия объект, но мы фактически изменили одинаковую ценность в источнике пицца объект. Этого не произойдет, если мы переназначив ценность свойства верхнего уровня:

// reassign the value of a top-level property in the copied object
pizzasCopy.margherita = {};

// log the copied object to the console
console.log(pizzasCopy.margherita); // This will log an empty object, as expected

// log the source object to the console
console.log(pizzas.margherita); // This will still log the original source object

То же самое произойдет, если мы используем Объект.assign () :

let pizzasCopy = Object.assign({}, pizzas);

// modify a value in the copy of pizzas
pizzasCopy.margherita.prices.small = '5.50';

// log the copied object to the console
console.log(pizzasCopy.margherita.prices.small); // This will log 5.50, as expected
 
// log the source object to the console
console.log(pizzas.margherita.prices.small); // This will also log 5.50 instead of 5.00!!

Решение

Несмотря на молчание Простая в использовании легкая библиотека JavaScript обычно используется в реакции , что позволяет нам мутировать копию объекта без изменения исходного источника. Мы можем получить эту библиотеку через NPM: NPM Установить Immutability Helper --save Отказ В глубокую копию нашего пицца объект, мы могли бы использовать Обновление () Метод, доступный в хелпере иммутабельности, передача объекта, который мы хотим скопировать в качестве первого аргумента и фактические данные для изменения в качестве второго.

import update from 'immutability-helper';

const pizzasCopy = update(pizzas, {margherita: {prices: {small: {$set: '5.50'}}}});

// log the copied object to the console
console.log(pizzasCopy.margherita.prices.small); // This will log 5.50, as expected

// log the source object to the console
console.log(pizzas.margherita.prices.small); // This will correctly log 5.00, the original price!!

Эта библиотека как целая куча Полезные команды и Это может копировать методы также. Определения методов на объектах не могут быть скопированы, например, использование методики «стандартного» метода глубокого копирования JSON Stringing и анализа объекта, как этот const.parse (JSON.Stringify (Soestobj)); Отказ

Обертывание

  • Распространенный синтаксис и Объект.assign () Позвольте нам сделать только мелкие копии объектов в JavaScript. Глубоко вложенные значения на самом деле поставляются там как ссылки на исходный объект.
  • Несмотря на молчание Простая в использовании легкая библиотека, которая позволяет нам глубоко копировать объект и легко манипулировать его с помощью выделенных методов.