Perbandingan mendetail antara Object.assign dan operator spread JavaScript untuk manipulasi objek, termasuk tolok ukur kinerja dan contoh kasus penggunaan praktis.
JavaScript Object.assign vs Spread: Perbandingan Kinerja & Kasus Penggunaan
JavaScript menawarkan berbagai cara untuk memanipulasi objek. Dua metode yang umum adalah Object.assign()
dan operator spread (...
). Keduanya memungkinkan Anda untuk menyalin properti dari satu atau lebih objek sumber ke objek target. Namun, keduanya berbeda dalam sintaksis, kinerja, dan mekanisme dasarnya. Artikel ini memberikan perbandingan komprehensif untuk membantu Anda memilih alat yang tepat untuk kasus penggunaan spesifik Anda.
Memahami Object.assign()
Object.assign()
adalah metode yang menyalin semua properti enumerable milik sendiri dari satu atau lebih objek sumber ke objek target. Metode ini memodifikasi objek target secara langsung dan mengembalikannya. Sintaksis dasarnya adalah:
Object.assign(target, ...sources)
target
: Objek target tempat properti akan disalin. Objek ini akan dimodifikasi.sources
: Satu atau lebih objek sumber dari mana properti akan disalin.
Contoh:
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target); // Output: { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target); // Output: true
Dalam contoh ini, properti dari source
disalin ke target
. Perhatikan bahwa properti b
ditimpa, dan returnedTarget
adalah objek yang sama dengan target
.
Memahami Operator Spread
Operator spread (...
) memungkinkan Anda untuk memperluas iterable (seperti array atau objek) menjadi elemen-elemen individual. Ketika digunakan dengan objek, operator ini membuat salinan dangkal dari properti objek ke dalam objek baru. Sintaksisnya sederhana:
const newObject = { ...sourceObject };
Contoh:
const source = { a: 1, b: 2 };
const newObject = { ...source };
console.log(newObject); // Output: { a: 1, b: 2 }
console.log(newObject === source); // Output: false
Di sini, newObject
berisi salinan properti dari source
. Yang penting, newObject
adalah objek *baru*, yang berbeda dari source
.
Perbedaan Utama
Meskipun Object.assign()
dan operator spread mencapai hasil yang serupa (menyalin properti objek), keduanya memiliki perbedaan krusial:
- Imutabilitas: Operator spread membuat objek baru, membiarkan objek asli tidak berubah (immutable).
Object.assign()
memodifikasi objek target secara langsung (mutable). - Penanganan Objek Target:
Object.assign()
memungkinkan Anda menentukan objek target, sementara operator spread selalu membuat yang baru. - Enumerabilitas Properti: Kedua metode menyalin properti yang enumerable. Properti yang non-enumerable tidak disalin.
- Properti Turunan: Tidak ada metode yang menyalin properti turunan dari rantai prototipe.
- Setter:
Object.assign()
memanggil setter pada objek target. Operator spread tidak; ia langsung menetapkan nilai. - Sumber Undefined atau Null:
Object.assign()
melewati objek sumbernull
danundefined
. Menyebarkannull
atauundefined
akan menimbulkan error.
Perbandingan Kinerja
Kinerja adalah pertimbangan penting, terutama saat berurusan dengan objek besar atau operasi yang sering dilakukan. Microbenchmark secara konsisten menunjukkan bahwa operator spread umumnya lebih cepat daripada Object.assign()
. Perbedaan ini berasal dari implementasi dasarnya.
Mengapa Operator Spread Lebih Cepat?
Operator spread sering kali mendapat manfaat dari implementasi internal yang dioptimalkan dalam mesin JavaScript. Operator ini dirancang khusus untuk pembuatan objek dan array, memungkinkan mesin untuk melakukan optimisasi yang tidak mungkin dilakukan dengan Object.assign()
yang lebih umum. Object.assign()
perlu menangani berbagai kasus, termasuk setter dan deskriptor properti yang berbeda, membuatnya secara inheren lebih kompleks.
Contoh Tolok Ukur (Ilustratif):
// Contoh sederhana (tolok ukur sebenarnya memerlukan lebih banyak iterasi dan pengujian yang kuat)
const object1 = { a: 1, b: 2, c: 3, d: 4, e: 5 };
const object2 = { f: 6, g: 7, h: 8, i: 9, j: 10 };
// Menggunakan Object.assign()
console.time('Object.assign');
for (let i = 0; i < 1000000; i++) {
Object.assign({}, object1, object2);
}
console.timeEnd('Object.assign');
// Menggunakan Operator Spread
console.time('Spread Operator');
for (let i = 0; i < 1000000; i++) {
({...object1, ...object2 });
}
console.timeEnd('Spread Operator');
Catatan: Ini adalah contoh dasar untuk tujuan ilustrasi. Tolok ukur di dunia nyata harus menggunakan pustaka benchmarking khusus (seperti Benchmark.js) untuk hasil yang akurat dan andal. Besarnya perbedaan kinerja dapat bervariasi berdasarkan mesin JavaScript, ukuran objek, dan operasi spesifik yang dilakukan.
Kasus Penggunaan: Object.assign()
Meskipun operator spread memiliki keunggulan kinerja, Object.assign()
tetap berharga dalam skenario tertentu:
- Memodifikasi Objek yang Ada: Ketika Anda perlu memperbarui objek secara langsung (mutasi) daripada membuat yang baru. Ini umum terjadi saat bekerja dengan pustaka manajemen state yang mutable atau ketika kinerja sangat penting, dan Anda telah memprofilkan kode Anda untuk memastikan bahwa menghindari alokasi objek baru memang bermanfaat.
- Menggabungkan Beberapa Objek ke dalam Satu Target:
Object.assign()
dapat secara efisien menggabungkan properti dari beberapa objek sumber ke dalam satu target. - Bekerja dengan Lingkungan JavaScript Lama: Operator spread adalah fitur ES6. Jika Anda perlu mendukung browser atau lingkungan lama yang tidak mendukung ES6,
Object.assign()
menyediakan alternatif yang kompatibel (meskipun Anda mungkin perlu polyfill). - Memanggil Setter: Jika Anda perlu memicu setter yang didefinisikan pada objek target selama penetapan properti,
Object.assign()
adalah pilihan yang tepat.
Contoh: Memperbarui State secara Mutable
let state = { name: 'Alice', age: 30 };
function updateName(newName) {
Object.assign(state, { name: newName }); // Memutasi objek 'state'
}
updateName('Bob');
console.log(state); // Output: { name: 'Bob', age: 30 }
Kasus Penggunaan: Operator Spread
Operator spread umumnya lebih disukai karena keunggulan imutabilitas dan kinerjanya dalam sebagian besar pengembangan JavaScript modern:
- Membuat Objek Baru dengan Properti yang Ada: Ketika Anda ingin membuat objek baru dengan salinan properti dari objek lain, seringkali dengan beberapa modifikasi.
- Pemrograman Fungsional: Operator spread sejalan dengan prinsip-prinsip pemrograman fungsional, yang menekankan imutabilitas dan menghindari efek samping.
- Pembaruan State React: Di React, operator spread umum digunakan untuk membuat objek state baru saat memperbarui state komponen secara immutable.
- Reducer Redux: Reducer Redux sering menggunakan operator spread untuk mengembalikan objek state baru berdasarkan action.
Contoh: Memperbarui State React secara Immutable
import React, { useState } from 'react';
function MyComponent() {
const [state, setState] = useState({ name: 'Charlie', age: 35 });
const updateAge = (newAge) => {
setState({ ...state, age: newAge }); // Membuat objek state baru
};
return (
<div>
<p>Name: {state.name}</p>
<p>Age: {state.age}</p>
<button onClick={() => updateAge(36)}>Increment Age</button>
</div>
);
}
export default MyComponent;
Salinan Dangkal vs. Salinan Dalam
Penting untuk dipahami bahwa Object.assign()
dan operator spread melakukan *salinan dangkal* (shallow copy). Ini berarti hanya properti tingkat atas yang disalin. Jika sebuah objek berisi objek atau array bersarang, hanya referensi ke struktur bersarang tersebut yang disalin, bukan struktur bersarang itu sendiri.
Contoh Salinan Dangkal:
const original = { a: 1, b: { c: 2 } };
const copy = { ...original };
copy.a = 3; // Memodifikasi 'copy.a', tetapi 'original.a' tetap tidak berubah
copy.b.c = 4; // Memodifikasi 'original.b.c' karena 'copy.b' dan 'original.b' menunjuk ke objek yang sama
console.log(original); // Output: { a: 1, b: { c: 4 } }
console.log(copy); // Output: { a: 3, b: { c: 4 } }
Untuk membuat *salinan dalam* (deep copy) (di mana objek bersarang juga disalin), Anda perlu menggunakan teknik seperti:
JSON.parse(JSON.stringify(object))
: Ini adalah metode sederhana namun berpotensi lambat. Metode ini tidak berfungsi dengan fungsi, tanggal, atau referensi sirkular.- Lodash's
_.cloneDeep()
: Fungsi utilitas yang disediakan oleh pustaka Lodash. - Fungsi rekursif kustom: Lebih kompleks tetapi memberikan kontrol paling besar atas proses salinan dalam.
- Structured Clone: Menggunakan
window.structuredClone()
untuk browser atau paketstructuredClone
untuk Node.js untuk menyalin objek secara mendalam.
Praktik Terbaik
- Pilih Operator Spread untuk Imutabilitas: Dalam sebagian besar aplikasi JavaScript modern, utamakan operator spread untuk membuat objek baru secara immutable, terutama saat bekerja dengan manajemen state atau pemrograman fungsional.
- Gunakan Object.assign() untuk Memutasi Objek yang Ada: Pilih
Object.assign()
ketika Anda secara spesifik perlu memodifikasi objek yang ada secara langsung. - Pahami Salinan Dangkal vs. Dalam: Sadarilah bahwa kedua metode melakukan salinan dangkal. Gunakan teknik yang sesuai untuk penyalinan dalam bila diperlukan.
- Lakukan Tolok Ukur Saat Kinerja Penting: Jika kinerja sangat penting, lakukan tolok ukur yang menyeluruh untuk membandingkan kinerja
Object.assign()
dan operator spread dalam kasus penggunaan spesifik Anda. - Pertimbangkan Keterbacaan Kode: Pilih metode yang menghasilkan kode yang paling mudah dibaca dan dipelihara untuk tim Anda.
Pertimbangan Internasional
Perilaku Object.assign()
dan operator spread umumnya konsisten di berbagai lingkungan JavaScript di seluruh dunia. Namun, perlu diperhatikan beberapa pertimbangan potensial berikut:
- Pengkodean Karakter: Pastikan kode Anda menangani pengkodean karakter dengan benar, terutama saat berurusan dengan string yang berisi karakter dari berbagai bahasa. Kedua metode menyalin properti string dengan benar, tetapi masalah pengkodean dapat muncul saat memproses atau menampilkan string ini.
- Format Tanggal dan Waktu: Saat menyalin objek yang berisi tanggal, perhatikan zona waktu dan format tanggal. Jika Anda perlu melakukan serialisasi atau deserialisasi tanggal, gunakan metode yang sesuai untuk memastikan konsistensi di berbagai wilayah.
- Pemformatan Angka: Wilayah yang berbeda menggunakan konvensi yang berbeda untuk pemformatan angka (misalnya, pemisah desimal, pemisah ribuan). Waspadai perbedaan ini saat menyalin atau memanipulasi objek yang berisi data numerik yang mungkin ditampilkan kepada pengguna di lokal yang berbeda.
Kesimpulan
Object.assign()
dan operator spread adalah alat yang berharga untuk manipulasi objek di JavaScript. Operator spread umumnya menawarkan kinerja yang lebih baik dan mempromosikan imutabilitas, menjadikannya pilihan utama di banyak aplikasi JavaScript modern. Namun, Object.assign()
tetap berguna untuk memutasi objek yang ada dan mendukung lingkungan yang lebih lama. Memahami perbedaan dan kasus penggunaannya akan membantu Anda menulis kode JavaScript yang lebih efisien, dapat dipelihara, dan tangguh.