Deep Clone sebuah Objek di JavaScript

Jan 31 2023
Klon dalam dari suatu objek adalah objek baru dengan salinan yang benar-benar terpisah dari semua properti, termasuk objek bersarang. Ini berbeda dari klon dangkal, di mana hanya properti tingkat pertama yang disalin dan objek bersarang direferensikan, bukan disalin.

Klon dalam dari suatu objek adalah objek baru dengan salinan yang benar-benar terpisah dari semua properti, termasuk objek bersarang. Ini berbeda dari klon dangkal, di mana hanya properti tingkat pertama yang disalin dan objek bersarang direferensikan, bukan disalin.

Ada beberapa cara untuk melakukan kloning objek dalam JavaScript, tetapi hanya satu yang terbaik.

Bisakah kita menggunakan JSON.parse & JSON.stringify? ❌

JSON.parse(JSON.stringify(obj)) — Metode ini menggunakan serialisasi JSON untuk membuat tiruan objek yang dalam. Ini berfungsi untuk objek yang tidak berisi referensi melingkar tetapi akan gagal jika objek berisi referensi melingkar.

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

Ambil ini sebagai contoh:

sumber:https://www.builder.io/blog/structured-clone

const calendarEvent = {
  title: "source: https://www.builder.io/blog/structured-clone",
  date: new Date(123),
  attendees: ["Lian"]
}
// JSON.stringify converted the `date` to a string
const copy = JSON.parse(JSON.stringify(calendarEvent))

{
  title: "source: https://www.builder.io/blog/structured-clone",
  date: "1970-01-01T00:00:00.123Z"
  attendees: ["Lian"]
}

Bisakah kita menggunakan metode Lodash atau garis bawah _.cloneDeep()? ❌ (Lebih suka Tidak)

sumber:https://www.builder.io/blog/structured-clone

Metode Lodash atau garis bawah _.cloneDeep() — Pustaka ini menyediakan fungsi kloning mendalam yang dapat menangani referensi melingkar dan kasus edge lainnya.

const _ = require('lodash');
const obj = { a: 1, b: { c: 2 } };
const clone = _.cloneDeep(obj);
console.log(clone);
// Output: { a: 1, b: { c: 2 } }

Dan ini, pada kenyataannya, berfungsi seperti yang diharapkan:

import cloneDeep from 'lodash/cloneDeep'
const calendarEvent = {
  title: "source: https://www.builder.io/blog/structured-clone",
  date: new Date(123),
  attendees: ["Lian"]
}
// ✅ All good!
const clonedEvent = structuredClone(calendarEvent)

sumber: https://www.builder.io/blog/structured-clone

Perkiraan ukuran ini hanya didasarkan pada pengimporan fungsi satu per satu. Jika Anda memilih metode pengimporan yang lebih umum, tanpa mempertimbangkan bahwa penggoyangan pohon mungkin tidak selalu efektif, Anda dapat membawa data sebanyak 25 kb hanya untuk fungsi tunggal ini.

sumber: https://www.builder.io/blog/structured-clone

Meskipun jumlah data ini tidak signifikan, ini tidak diperlukan dalam situasi kami karena browser modern sudah memiliki fitur Klon Terstruktur bawaan.

Bisakah kita menggunakan operator spread untuk mengkloning sebuah objek? ❌

Tidak, operator sebaran ( ...) dalam JavaScript hanya melakukan tiruan dangkal dari suatu objek. Saat menggunakan operator sebaran untuk mengkloning sebuah objek, objek bersarang apa pun akan tetap direferensikan daripada disalin, jadi perubahan pada objek bersarang di objek yang dikloning juga akan memengaruhi objek aslinya.

Berikut contohnya:

const original = {a: 1, b: {c: 2}};
const clone = {...original};

console.log(clone);
// Output: {a: 1, b: {c: 2}}

clone.b.c = 3;

console.log(original);
// Output: {a: 1, b: {c: 3}}

Bisakah kita menggunakan Object.assign untuk mengkloning sebuah objek dalam javascript? ❌

Tidak, Object.assign()metode dalam JavaScript hanya melakukan tiruan dangkal dari suatu objek. Saat menggunakan Object.assign()untuk mengkloning objek, objek bersarang apa pun akan tetap direferensikan daripada disalin, jadi perubahan pada objek bersarang di objek yang dikloning juga akan memengaruhi objek asli.

Berikut contohnya:

const original = {a: 1, b: {c: 2}};
const clone = Object.assign({}, original);

console.log(clone);
// Output: {a: 1, b: {c: 2}}

clone.b.c = 3;

console.log(original);
// Output: {a: 1, b: {c: 3}}

Klon Terstruktur ✅

Itu structured cloneadalah konsep dalam JavaScript yang mengacu pada proses pembuatan klon yang dalam dari suatu objek, termasuk objek dan larik bersarangnya, serta struktur data kompleks lainnya. Algoritme ini structured clonedigunakan oleh beberapa API dalam JavaScript, seperti postMessagemetode untuk komunikasi antar objek jendela (misalnya antara halaman dan iframe), IndexedDBAPI untuk menyimpan dan mengambil data di browser, dan Service WorkersAPI untuk pemrosesan permintaan jaringan di latar belakang.

Algoritme structured clonebekerja dengan menyalin semua properti objek secara rekursif, termasuk objek dan array bersarang, ke dalam objek baru dengan struktur dan nilai yang sama. Itu dapat menangani berbagai tipe data, termasuk fungsi, tanggal, ekspresi reguler, array, dan objek.

Algoritme structured cloneadalah alat yang ampuh untuk membuat klon mendalam dari struktur data kompleks dalam JavaScript, dan sering digunakan untuk melakukan operasi kompleks pada data di browser atau lingkungan JavaScript lainnya.

Implementasi khusus menggunakan rekursi — Metode ini melibatkan pendefinisian fungsi yang menggunakan rekursi untuk membuat tiruan mendalam dari suatu objek.

const original = { a: 1, b: { c: new Date() } };

const deepClone = (obj) => {
  if (obj === null || typeof obj !== "object") return obj;
  let clone = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] =
        obj[key] instanceof Date
          ? new Date(obj[key].getTime())
          : deepClone(obj[key]);
    }
  }
  return clone;
};

const clone = deepClone(original);

console.log(clone);
// Output: {a: 1, b: {c: 2022-12-31T08:00:00.000Z}}

clone.b.c.setFullYear(2023);

console.log(original);
// Output: {a: 1, b: {c: 2022-12-31T08:00:00.000Z}}