Все о копировании объектов в JavaScript

Как часто вы пытались клонировать элемент в Javascript, и результат был не таким, как вы ожидали? В этой статье мы объясним основные идеи, лежащие в основе клонирования, чтобы гарантировать, что вы всегда используете лучший выбор.

Различие между поверхностным копированием и глубоким копированием

Javascript имеет 2 типа копирования объекта:

1. Поверхностное копирование : подразумевает, что первый уровень элемента реплицируется. Ссылаются на более глубокие уровни.

2. Глубокое копирование: означает, что копируются все уровни объекта . Это точная копия объекта.

Для получения более глубокого опыта я попросил ChatGPT сгенерировать мне вложенный объект со всеми возможными типами данных, и он вернул мне это:

const nestedObject1 = {
    string: 'Hello, world!',
    number: 42,
    boolean: true,
    nullValue: null,
    undefinedValue: undefined,
    array: ['apple', 'banana', 'cherry'],
    object: {
        nestedString: 'This is a nested string',
        nestedNumber: 123,
        nestedBoolean: false
    },
    date: new Date(),
    regexp: /hello/g,
    function: function () {
        console.log('This is a function');
    },
    symbol: Symbol('symbol')
};

Самый простой и худший метод копирования — использование оператора равенства (=).

let object2 = nestedObject1
object2.string = "Hello from object2"
object2.number = 45
object2.array[2] = "Strawberry"
object2.object.nestedNumber = 66

Мелкая копия:

Чтобы получить поверхностное копирование, мы можем использовать оператор распространения ({…}) или функцию Object.assign() .

  1. Оператор спреда
  2. let object2 = { ...nestedObject1 }
    object2.string = "Hello from object2"
    object2.number = 45
    object2.array[2] = "Strawberry"
    object2.object.nestedNumber = 66
    

Это связано с тем, что неглубокая копия только что создала еще один указатель на более глубокие уровни и, следовательно, создала ссылку, а не копию.

2. Функция Object.assign()

let object2 = Object.assign({}, nestedObject1)
object2.string = "Hello from object2"
object2.number = 45
object2.array[2] = "Strawberry"
object2.object.nestedNumber = 66

Мы видим аналогичный результат для оператора распространения.

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

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

Чтобы получить глубокую копию, мы рассмотрим следующие методы:
- взлом JSON.parse и JSON.stringify
- использование пользовательской функции
- использование сторонней библиотеки (lodash)
- встроенный API

  1. Взлом JSON.parse и JSON.stringify

let object2 = JSON.parse(JSON.stringify(nestedObject1))
object2.string = "Hello from object2"
object2.number = 45
object2.array[2] = "Strawberry"
object2.object.nestedNumber = 66

Как мы видим, новый объект понес огромные потери данных . Наряду с этим, такие методы, как date, претерпели изменение типа.
Следовательно, этот метод крайне неэффективен при работе с не примитивными типами данных, такими как функции, регулярные выражения, символы, неопределенные и т. д.

2. Использование пользовательской функции

Я создал функцию глубокого копирования с именем deepcopy() , написал кучу кода и внес те же изменения.

function deepCopy(obj) {
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }
    let copy = Array.isArray(obj) ? [] : {};
    Object.keys(obj).forEach((key) => {
        copy[key] = deepCopy(obj[key]);
    });
    return copy;
}
let object2 = deepCopy(nestedObject1)
object2.string = "Hello from object2"
object2.number = 45
object2.array[2] = "Strawberry"
object2.object.nestedNumber = 66

Как мы видим, этот метод также вызвал массовую потерю данных, аналогичную методам JSON.parse и JSON.stringify.

3. Использование сторонней библиотеки (lodash)

Пока что эта библиотека вернула очень хорошую копию данных с самой минимальной потерей данных и максимальной эффективностью.
Вы можете проверить это наhttps://lodash.com/

Чтобы использовать эту библиотеку, вам понадобится npm или yarn и скрипт типа модуля.

const load = require('lodash');
const object2 = load.cloneDeep(nestedObject1);
object2.string = "Hello from object2"
object2.number = 45
object2.array[2] = "Strawberry"
object2.object.nestedNumber = 66

Это был самый эффективный способ сделать копию. Однако проблема здесь остается в том, что не всегда нам нужен пакет или модуль в формате javascript. Для этого существует следующий метод.

4. Использование встроенного API

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

const nestedObject1 = {
    string: 'Hello, world!',
    number: 42,
    boolean: true,
    nullValue: null,
    undefinedValue: undefined,
    array: ['apple', 'banana', 'cherry'],
    object: {
        nestedString: 'This is a nested string',
        nestedNumber: 123,
        nestedBoolean: false
    },
    date: new Date(),
    regexp: /hello/g,
}

let object2 = structuredClone(nestedObject1)
object2.string = "Hello from object2"
object2.number = 45
object2.array[2] = "Strawberry"
object2.object.nestedNumber = 66

API структурированного клона работает в браузерах, и, учитывая вышеупомянутые ограничения, он по-прежнему имеет оптимальное решение с учетом всевозможных ограничений.

Надеюсь, вы все нашли этот блог информативным и теперь подробно изучили различные методы копирования объектов.

Suggested posts

Революция без программирования: обеспечение процветания бизнеса с помощью Webflow, Framer, Bubble.io,

Революция без программирования: обеспечение процветания бизнеса с помощью Webflow, Framer, Bubble.io,

Отправляйтесь в захватывающее путешествие инноваций и успеха, используя неиспользованный потенциал этих удивительных платформ без кода. Позвольте мне поделиться с вами историей о Сапне, замечательной женщине-предпринимателе.

Мои наиболее используемые ресурсы кодирования

Мои наиболее используемые ресурсы кодирования

На этой неделе я получил электронное письмо от участника ежедневного списка рассылки. Они хотели знать: какие ресурсы вы посещаете ежедневно, еженедельно и ежемесячно? Отличный вопрос! Я рад поделиться некоторыми мыслями о моем рабочем процессе и основных ресурсах, которые я использую.

Related posts

Сбор OSINT для поиска угроз

Сбор OSINT для поиска угроз

Привет, киберлюбители! Добро пожаловать обратно в серию OSINT по поиску угроз. В первой статье я рассказал вам об OSINT и его важности для поиска угроз.

Как спасти планету и заработать деньги

Как спасти планету и заработать деньги

Сколько раз вы, не задумываясь, выбрасывали пластиковую бутылку, стеклянную банку, алюминиевую банку или пакет экологически чистой энергии? Сколько раз вы хотели получить что-то взамен за их переработку? Если вы похожи на большинство людей, ответ, вероятно, много раз. Переработка часто рассматривается как хлопотное дело, рутинная работа или обязанность, не приносящая немедленных или ощутимых выгод.

Убийство Джордана Нили и проблема «патриотического» расизма

Могут ли США сделать важный шаг и не приравнивать расистское поведение к тому, чтобы быть хорошим американцем?

Убийство Джордана Нили и проблема «патриотического» расизма

[Предупреждение: в этом эссе есть снимки экрана, на которых люди восхваляют убийцу Джордана Нили.] Сотрудники правоохранительных органов наконец — и, возможно, неохотно — предъявили обвинение в этом убийстве Дэниелу Пенни, человеку, который душил Джордана Нили, пока тот не умер.

Поиск информации о доменных именах

Отрывок из книги «Маленькие программные инструменты Sharp» Брайана П. Хогана.

Поиск информации о доменных именах

Когда вы делаете запрос на facebook.com, ваш компьютер ищет доменное имя, чтобы преобразовать это доменное имя в IP-адрес, чтобы ваш компьютер мог установить это соединение.