Dalam artikel ini, Anda akan mempelajari apa itu penyalinan dangkal dan dalam, dan cara terbaik untuk menyalin objek dalam JavaScript
Penyalinan Dangkal vs. Menyalin Dalam
Dalam operasi penugasan ulang yang melibatkan tipe data primitif seperti string, angka, dan boolean, variabel asli disalin oleh JavaScript.
Sebagai contoh, perhatikan kode berikut
1
let x = 3
2
y = x // x is copied into y
3
4
y++ // y is incremented
5
6
console.log[y] // now 4
let x = 30
let x = 31
Dalam hal ini, nilai
3_31 disalin ke
332, lalu
333 terputus dari
332. Jadi bermutasi
332 tidak mempengaruhi
333
Sebaliknya, dengan tipe data non-primitif seperti array dan objek, hanya referensi ke nilai yang diteruskan. Jadi saat salinannya dimutasi, yang asli juga akan dimutasi. Ini juga dikenal sebagai penyalinan dangkal
1
let x = 33
2
3
let x = 36
4
let x = 38
5
6
21
let x = 30
23
Sebaliknya, jika kita ingin menyalin sebuah objek sehingga kita dapat memodifikasinya tanpa mempengaruhi objek aslinya, kita perlu membuat salinan yang dalam.
5 Cara untuk Menyalin Objek Dalam JavaScript
Dalam JavaScript, kita dapat melakukan penyalinan pada objek menggunakan metode berikut
MetodeProsKonstruktif dan langsung, defaultnya hanya salinan dangkal objeksalinan dalam objek bersarangtidak menyalin fungsimenyalin anggota langsung dari suatu objek—termasuk fungsitidak menyalin dalam objek bersarangsintaks sederhana, cara yang lebih disukai untuk menyalin objektidak menyalin dalam objek bersarangkloning objek bersarang termasuk fungsimenambahSemua metode ini memiliki pro dan kontra. Mari kita lihat lebih dekat masing-masing
Shallow Copy Object by Assignment
Anda dapat membuat salinan objek yang dangkal hanya dengan menugaskan objek asli ke variabel baru.
Perhatikan objek berikut
1
25
2
27
3
29
4
y = x // x is copied into y1
5
y = x // x is copied into y3
Untuk membuat salinan objek
3_42, kami menetapkan objek ke variabel baru seperti itu
1
y = x // x is copied into y5
2
3
y = x // x is copied into y8
4
30
5
6
33
let x = 30
35
36
37
38
39
40
41
42
43
44
45
46
35
48
37
y++ // y is incremented0
39
y++ // y is incremented2
41
y++ // y is incremented4
43
y++ // y is incremented6
y++ // y is incremented7
Seperti yang diamati pada output konsol, kami sekarang telah menyalin objek dari
342 ke
344
Namun, yang kami lakukan hanyalah membuat referensi ke objek aslinya. Setiap kali kami mengubah properti di objek
344, kami juga akan mengubah objek asli [
342] seperti yang kami lakukan di kode berikut
1
y++ // y is incremented9
2
3
y = x // x is copied into y8
4
30
5
6
33
let x = 30
35
36
61
38
39
40
41
42
43
44
35
46
61
48
39
y++ // y is incremented0
41
y++ // y is incremented2
43
y++ // y is incremented4
y++ // y is incremented7
Jadi ketika tipe data non-primitif [array atau objek] ditugaskan ke variabel baru, JavaScript membuat salinan dangkal dari objek asli
Salin Objek Dengan 3
38 dan 3
39
Metode
338 mengambil objek dan membuat string JSON darinya. Metode
339 mengurai string dan menampilkan objek JavaScript
Kita dapat menggabungkan kedua metode ini untuk membuat salinan objek dengan cara berikut
1
25
2
27
3
29
4
y = x // x is copied into y1
5
y = x // x is copied into y3
6
let x = 30
let x = 312
36
38
y = x // x is copied into y8
40
30
42
44
let x = 320
46
35
48
37
y++ // y is incremented0
39
y++ // y is incremented2
41
y++ // y is incremented4
43
y++ // y is incremented6
35
let x = 333
37
let x = 335
39
let x = 337
41
let x = 339
43
let x = 341
y++ // y is incremented7
Saat objek salinan dimutasi, objek aslinya tetap sama
1
let x = 344
2
3
y = x // x is copied into y8
4
30
5
6
let x = 320
let x = 30
35
36
37
38
39
40
41
42
43
44
35
46
let x = 366
48
39
y++ // y is incremented0
41
y++ // y is incremented2
43
y++ // y is incremented4
y++ // y is incremented7
Namun, ada satu peringatan untuk menggunakan pendekatan ini.
3_38 tidak menyalin fungsi
Misalkan kita memiliki metode dalam objek kita
3_42 disebut
353
1
25
2
27
3
29
4
let x = 382
5
let x = 384
6
let x = 386
let x = 30
let x = 388________4______6
y = x // x is copied into y3
Fungsi tidak akan tersedia di objek yang disalin. Dengan demikian, metode ini mencapai salinan dalam hanya jika tidak ada fungsi di dalam objek
Salin Objek Dengan 3
54
Sebelum ES6,
354 adalah cara paling populer untuk menyalin objek secara mendalam
1
25
2
27
3
29________5___
let x = 382
5__________________________________________________________________________________________________________________________________________________________________________
3_54 akan menyalin semuanya ke objek baru, termasuk fungsi apa pun. Memutasi objek yang disalin juga tidak memengaruhi objek asli
1
let x = 344
2
3
y = x // x is copied into y8
4
30
5
6
let x = 320
let x = 30
35
36
223
38
225
40
227
42
229
44
231
46
233
48
43
y++ // y is incremented0
35
y++ // y is incremented2
239
y++ // y is incremented4
225
y++ // y is incremented6
227
let x = 333
229
let x = 335
231
let x = 337
233
let x = 339
43
let x = 341
y++ // y is incremented7
Namun, satu hal yang perlu diingat tentang
354 adalah bahwa metode ini hanya melakukan penyalinan dalam sebagian pada objek
Untuk memahami apa artinya, mari kita pertimbangkan hal berikut
1
25
2
27
3
29________5___
let x = 382
5
2_______________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________g EX
Seperti yang diamati, kami menambahkan properti location dan memberikan objek sebagai nilainya. Sekarang kami memiliki struktur yang lebih kompleks yang berisi objek bersarang.
Setiap kali kami mengubah properti di dalam objek bersarang [di
344], itu juga akan mengubah properti yang sama di objek asli [
359]. Mari lihat
1
let x = 344
2
276
3
4
5
y = x // x is copied into y8
6
30
let x = 30
36
let x = 320
38
35
40
37
42
39
44
293
46
295
48
297
y++ // y is incremented0
41
y++ // y is incremented2
43
y++ // y is incremented4
45
y++ // y is incremented6
35
let x = 333
let x = 366
let x = 335
39
let x = 337
293
let x = 339
295
let x = 341
297
y = x // x is copied into y16
41
y = x // x is copied into y18
43
y = x // x is copied into y20
y++ // y is incremented7
Meskipun properti
3_60 di objek asli tetap tidak tersentuh, properti
361 dimutasi oleh operasi penugasan kembali
Oleh karena itu, metode
354 harus digunakan untuk menyalin secara mendalam objek yang tidak memiliki objek bersarang.
Cara Terbaik untuk Menyalin Dalam di JavaScript. Operator Penyebaran
Cara lain untuk menyalin objek dalam JavaScript adalah dengan operator penyebaran ES6. Menggunakan tiga titik [
3_40] mengumpulkan semua nilai pada objek asli ke objek lain
1
25
2
27
3
29
4
y = x // x is copied into y1
5
y = x // x is copied into y3
6
let x = 30
y = x // x is copied into y34
36
38
y = x // x is copied into y37
40
42
let x = 320
44
35
46
37
48
39
y++ // y is incremented0
41
y++ // y is incremented2
43
y++ // y is incremented4
y++ // y is incremented7
Namun, seperti
354, operator spread hanya membuat salinan sebagian. Jadi objek apa pun dengan objek bersarang tidak akan disalin dalam-dalam
Untuk membuat salinan lengkap dengan operator spread, kita harus menulis beberapa kode tambahan
Pertimbangkan objek pengguna yang sama tetapi dengan objek bersarang
1
y = x // x is copied into y54
2
27
3
29
4
let x = 382
5_________________________________________________________________________________________________________________________________________________________________________________________________________________________g EX
Untuk menghindari mutasi objek asli, yaitu
342, kita harus menyebarkan objek salinan sebelum membuat perubahan langsung ke salah satu propertinya. Untuk objek bersarang apa pun, kita juga harus menyebarkan sub-objek itu sebelum membuat perubahan pada propertinya
1
y = x // x is copied into y73
2
y = x // x is copied into y75
3
y = x // x is copied into y77
4
y = x // x is copied into y79
5
y = x // x is copied into y81
6
y = x // x is copied into y83
let x = 30
y = x // x is copied into y85________4______6________3______3
Di sini, kami mengubah
3_60, yang merupakan properti tingkat atas di
344, dan
361, yang merupakan sub-properti
Kali ini, operasi penyebaran akan memberikan salinan dalam yang lengkap di mana objek asli tidak akan terpengaruh oleh mutasi apa pun pada salinan [
344]
1
y = x // x is copied into y8
2
30
3
4
let x = 320
5
35
6
37
let x = 30
39
36
293
38
304
40
297
42
41
44
43
46
45
48
35
y++ // y is incremented0
let x = 366
y++ // y is incremented2
39
y++ // y is incremented4
293
y++ // y is incremented6
295
let x = 333
297
let x = 335
41
let x = 337
43
let x = 339
y++ // y is incremented7
Gunakan Lodash 3
41 untuk Penyalinan Mendalam
Lodash juga menyediakan metode utilitas
3_71 untuk kloning objek dalam JavaScript.
Kesimpulan
Seperti yang Anda lihat, ada sejumlah cara untuk menyalin variabel dalam JavaScript. Tak satu pun dari mereka sempurna untuk setiap kesempatan, jadi Anda harus berhati-hati memilih metode terbaik untuk setiap situasi