JavaScript

Як клонувати (копіювати) об’єкт і масив у JavaScript

Last updated: 21.02.2026
Views: 76
Клонування об’єктів і масивів – не така проста тема, як може здатися на перший погляд. Клонування об’єктів і масивів у JavaScript можна здійснювати за допомогою різних методів залежно від складності (поверхневе чи глибоке клонування).

Клонування масиву

1. Використання оператору spread (...):

const originalArray = [1, 2, 3];
const clonedArray = [...originalArray];
console.log(clonedArray); // Output: [1, 2, 3]

2. Використання Array.prototype.slice():

const originalArray = [1, 2, 3];
const clonedArray = originalArray.slice();
console.log(clonedArray); // Output: [1, 2, 3]

3. Використання Array.from():

const originalArray = [1, 2, 3];
const clonedArray = Array.from(originalArray);
console.log(clonedArray); // Output: [1, 2, 3]

4. Використання structuredClone() (глибоке клонування):

const originalArray = [1, { key: "value" }];
const clonedArray = structuredClone(originalArray);
console.log(clonedArray); // Output: [1, { key: "value" }]

Клонування об’єкта

1. Використання оператору spread (...):

const originalObject = { a: 1, b: 2 };
const clonedObject = { ...originalObject };
console.log(clonedObject); // Output: { a: 1, b: 2 }

2. Використання Object.assign():

const originalObject = { a: 1, b: 2 };
const clonedObject = Object.assign({}, originalObject);
console.log(clonedObject); // Output: { a: 1, b: 2 }

3. Використання structuredClone() (глибоке клонування):

const originalObject = { a: 1, b: { c: 2 } };
const clonedObject = structuredClone(originalObject);
console.log(clonedObject); // Output: { a: 1, b: { c: 2 } }

4. Використання JSON.parse() та JSON.stringify() (глибоке клонування):

const originalObject = { a: 1, b: { c: 2 } };
const clonedObject = JSON.parse(JSON.stringify(originalObject));
console.log(clonedObject); // Output: { a: 1, b: { c: 2 } }

Цей метод не підтримує функції, undefined, Symbol або циклічні посилання.

Глибоке клонування проти поверхневого клонування

  • Поверхнев клонування (наприклад, за допомогою ..., slice() або Object.assign()):
    Клонує лише перший рівень об’єкта або масиву. Вкладені об’єкти або масиви залишаються посиланнями на оригінал.
  • Глибоке клонування (наприклад, structuredClone() або JSON.parse(JSON.stringify())):
    Клонує всю структуру, включаючи вкладені об’єкти чи масиви.

Коли використовувати кожен метод

  • Використовуйте поверхневе клонування для простих структур.
  • Використовуйте глибоке клонування, якщо об’єкт або масив містить вкладені структури, і вам потрібно уникати посилань на вихідні дані.

Клонування масиву або об’єкта, який містить методи (функції)

Поверхневе клонування

Використання оператора spread (...) або Object.assign()

  • Функції в об’єкті чи масиві обробляються як будь-яка інша властивість.
  • Посилання на функцію копіюється до клонованого об’єкта чи масиву.
  • Оригінальна та клонована версії використовуватимуть ту саму функцію в пам’яті.
const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};
const clonedObject = { ...originalObject };

console.log(clonedObject.method()); // Output: 42
console.log(clonedObject.method === originalObject.method); // Output: true (same reference)

Для масивів: якщо масив містить функції, посилання на ці функції копіюються. Використання оператора розширення (...) або slice()

const originalArray = [1, 2, function () { return 42; }];
const clonedArray = [...originalArray];

console.log(clonedArray[2]()); // Output: 42
console.log(clonedArray[2] === originalArray[2]); // Output: true (same reference)

Глибоке клонування

Використання JSON.parse(JSON.stringify())

  • Методи (функції) буде втрачено, оскільки JSON підтримує лише серіалізовані типи даних (наприклад, числа, рядки, масиви та об’єкти).
  • Будь-які властивості, що містять функції, не існуватимуть у клонованому об’єкті чи масиві.
const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};
const clonedObject = JSON.parse(JSON.stringify(originalObject));

console.log(clonedObject.method); // Output: undefined

Використання structuredClone() (Глибоке клонування)
Функції не клонуються. Структуроване клонування не підтримує функції та видаляє їх із клонованого об’єкта чи масиву.

const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};
const clonedObject = structuredClone(originalObject);

console.log(clonedObject.method); // Output: undefined

Ключові моменти, про які слід пам’ятати

1. Поверхневе клонування:

  • Функції копіюються за посиланням, тобто клоновані та вихідні об’єкти/масиви використовуватимуть ту саму функцію.

2. Глибоке клонування:

  • Функції зазвичай втрачаються (видаляються) під час використання таких методів, як JSON.parse(JSON.stringify()) або structuredClone(), оскільки їх не можна серіалізувати.

3. Якщо вам потрібно клонувати об’єкт або масив за допомогою методів, вам може знадобитися написати спеціальну функцію клонування для явної обробки функцій або використовувати сторонні бібліотеки.

Власне клонування для об’єктів із методами

Ви можете керувати функціями вручну у своїй логіці клонування:

function customClone(obj) {
    const clone = Array.isArray(obj) ? [] : {};
    for (const key in obj) {
        if (typeof obj[key] === 'function') {
            clone[key] = obj[key]; // Copy functions by reference
        } else if (typeof obj[key] === 'object' && obj[key] !== null) {
            clone[key] = customClone(obj[key]); // Recursively clone objects
        } else {
            clone[key] = obj[key]; // Copy primitives
        }
    }
    return clone;
}

const original = {
    value: 42,
    method() {
        return this.value;
    }
};

const cloned = customClone(original);

console.log(cloned.method()); // Output: 42
console.log(cloned.method === original.method); // Output: true (same reference)

Цей підхід гарантує збереження функцій при глибокому клонуванні інших властивостей.

Використання сторонніх бібліотек

У проектах я часто використовую Lodash або jQuery. Обидві ці бібліотеки мають методи глибокого клонування. Під час використання Lodash або jQuery для виконання глибокого клонування обидві бібліотеки обробляють функції по-іншому, ніж такі нативні методи, як JSON.parse(JSON.stringify()) або structuredClone().

Глибоке клонування за допомогою Lodash

Використання Lodash _.cloneDeep():

  • Lodash виконує глибоке клонування об’єкта або масиву, включаючи вкладені структури.
  • Функції (методи) в об’єкті чи масиві копіюються за посиланням. Це означає, що функція в клонованому об’єкті чи масиві вказуватиме на те саме посилання на пам’ять, що й оригінал.
const _ = require('lodash');

const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};

const clonedObject = _.cloneDeep(originalObject);

console.log(clonedObject.method()); // Output: 42
console.log(clonedObject.method === originalObject.method); // Output: true (same reference)

Lodash не видаляє функції, на відміну від JSON.parse(JSON.stringify()), але він не створює нову копію функції. Він зберігає посилання на оригінал.

Глибоке клонування за допомогою jQuery

Використання $.extend() jQuery:

  • $.extend() jQuery використовується для клонування об’єктів. Щоб отримати глибокий клон, ви передаєте true як перший аргумент.
  • Як і Lodash, jQuery копіює функції за посиланням.
const originalObject = {
    value: 42,
    method: function () {
        return this.value;
    }
};

const clonedObject = $.extend(true, {}, originalObject);

console.log(clonedObject.method()); // Output: 42
console.log(clonedObject.method === originalObject.method); // Output: true (same reference)

Обмеження $.extend():

  • Механізм клонування jQuery простіший і менш надійний порівняно з Lodash.
  • Він не обробляє деякі складні випадки використання (наприклад, циклічні посилання) так ефективно, як Lodash.
author
Автор: Ігор Рибалко
Працюю фронтенд розробником з 2014 року. Основний стек технологій - Vue.js і WordPress

Схожі записи:

  • Способи створення об’єктів у JavaScript
    Існує декілька способів створення об’єктів у JavaScript. Тип даних Object відіграє вирішальну роль у JS. Об’єкт — це невпорядкований набір пар ключ-значення. Може містити...
  • Як створити власний плагін jQuery
    Зручність плагіна jQuery полягає в тому, що ви можете використовувати один і той же код кілька разів для різних об’єктів. У цьому випадку копіювати та вставляти код не по...
  • Ітерація елементів масиву без циклу
    Приклади дуже абстрактні, оскільки цикли існують. Наша умова буде такою. Потрібно вибрати всі елементи масиву за заданим атрибутом. Або, якщо сказати точніше, потрібно ві...

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *