Trong bài viết này, bạn sẽ tìm hiểu sao chép nông và sâu là gì, cũng như cách tốt nhất để sao chép sâu một đối tượng trong JavaScript Show
Sao chép nông vs. Sao chép sâuTrong thao tác gán lại liên quan đến các kiểu dữ liệu nguyên thủy như chuỗi, số và booleans, biến ban đầu được sao chép bởi JavaScript. Ví dụ: xem xét đoạn mã sau 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 Trong trường hợp này, giá trị 331 được sao chép vào 332, sau đó 333 bị ngắt kết nối khỏi 332. Vì vậy, đột biến 332 không ảnh hưởng đến 333 Ngược lại, với các kiểu dữ liệu không nguyên thủy như mảng và đối tượng, chỉ một tham chiếu đến các giá trị được truyền. Vì vậy, khi bản sao bị biến đổi, bản gốc cũng bị biến đổi. Điều này còn được gọi là sao chép nông 1 let x = 33 2 3 let x = 36_______5_______ let x = 38 5 62_______1 let x = 30 23 Thay vào đó, nếu chúng ta muốn sao chép một đối tượng để có thể sửa đổi nó mà không ảnh hưởng đến đối tượng ban đầu, chúng ta cần tạo một bản sao sâu. 5 cách để sao chép sâu các đối tượng trong JavaScriptTrong JavaScript, chúng ta có thể thực hiện sao chép đối tượng bằng các phương thức sau MethodProsRõ ràng và trực tiếp, mặc địnhchỉ sao chép nông các đối tượngsao chép sâu các đối tượng lồng nhaukhông sao chép chức năngsao chép các thành viên trực tiếp của một đối tượng—bao gồm cả các chức năngkhông sao chép sâu các đối tượng lồng nhaucú pháp đơn giản, cách ưa thích để sao chép một đối tượngkhông sao chép sâu các đối tượng lồng nhau sao chép các đối tượng lồng nhau bao gồm các hàm thêmCác phương pháp này đều có ưu và nhược điểm. Chúng ta hãy xem xét kỹ hơn từng người trong số họ Sao chép nông một đối tượng theo nhiệm vụBạn có thể tạo một bản sao nông của một đối tượng bằng cách gán đối tượng ban đầu cho một biến mới. Xét đối tượng sau 1 25_______2_______ 27_______4_______ 29 4___ y = x // x is copied into y1 5 y = x // x is copied into y3 Để tạo một bản sao của đối tượng 342, chúng ta gán đối tượng cho một biến mới như vậy 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 Theo quan sát trong đầu ra của bảng điều khiển, chúng tôi hiện đã sao chép đối tượng từ 342 vào 344 Tuy nhiên, tất cả những gì chúng ta đã làm là tạo một tham chiếu đến đối tượng ban đầu. Bất cứ khi nào chúng ta thay đổi một thuộc tính trong đối tượng 344, cuối cùng chúng ta cũng sẽ thay đổi đối tượng ban đầu (_______4_______42) như chúng ta thực hiện trong đoạn mã sau 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 Vì vậy, khi một kiểu dữ liệu không nguyên thủy (mảng hoặc đối tượng) được gán cho một biến mới, JavaScript sẽ tạo một bản sao nông của đối tượng ban đầu Sao chép một đối tượng với 338 và 339Phương thức 338 nhận một đối tượng và tạo một chuỗi JSON từ nó. Phương thức 339 phân tích cú pháp một chuỗi và trả về một đối tượng JavaScript Chúng ta có thể kết hợp cả hai phương pháp này để tạo một bản sao của đối tượng theo cách sau 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 Khi đối tượng sao chép bị thay đổi, đối tượng ban đầu vẫn giữ nguyên 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 Tuy nhiên, có một lưu ý khi sử dụng phương pháp này. 338 không sao chép chức năng Giả sử chúng ta có một phương thức trong đối tượng 342 được gọi là 353 1 25 2 27_______4_______ 29 41_______82 5 let x = 384 6 let x = 386 let x = 30 let x = 388 36 y = x // x is copied into y3 Chức năng sẽ không khả dụng trong đối tượng được sao chép. Do đó, phương pháp này chỉ đạt được bản sao sâu nếu không có chức năng nào trong đối tượng Sao chép một đối tượng với 354Trước ES6, 354 là cách phổ biến nhất để sao chép sâu một đối tượng 1 25 2 27 3 29 4___ let x = 382 5 let x = 384 6 let x = 386 let x = 30 let x = 388 36 y = x // x is copied into y3 38 40 209 354 sẽ sao chép mọi thứ vào đối tượng mới, bao gồm mọi chức năng. Thay đổi đối tượng được sao chép cũng không ảnh hưởng đến đối tượng ban đầu 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 Tuy nhiên, một điều cần nhớ về 354 là phương thức này chỉ thực hiện sao chép sâu một phần đối tượng Để hiểu điều đó có nghĩa là gì, chúng ta hãy xem xét những điều sau đây 1 25 2 27 3 29 41_______82 5 263 6 265 let x = 30 let x = 388 36 y = x // x is copied into y3 38 40 272 Theo quan sát, chúng tôi đã thêm thuộc tính vị trí và chuyển một đối tượng làm giá trị của nó. Bây giờ chúng ta có một cấu trúc phức tạp hơn chứa đối tượng lồng nhau. Bất cứ khi nào chúng ta thay đổi một thuộc tính trong đối tượng lồng nhau (trong 344), nó cũng sẽ thay đổi thuộc tính tương tự trong đối tượng ban đầu ( 359). chúng ta hãy xem 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 Trong khi thuộc tính 360 trong đối tượng ban đầu vẫn không bị ảnh hưởng, thì thuộc tính 361 đã bị biến đổi do thao tác chỉ định lại Do đó, nên sử dụng phương pháp 354 để sao chép sâu các đối tượng không có đối tượng lồng nhau. Cách tốt nhất để sao chép sâu trong JavaScript. Toán tử lây lanMột cách khác để sao chép sâu các đối tượng trong JavaScript là sử dụng toán tử trải rộng ES6. Sử dụng dấu ba chấm ( 340) thu thập tất cả các giá trị trên đối tượng ban đầu vào một đối tượng khác 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 Tuy nhiên, giống như với 354, toán tử trải rộng chỉ sao chép một phần. Vì vậy, bất kỳ đối tượng nào có đối tượng lồng nhau sẽ không được sao chép sâu Để tạo một bản sao sâu hoàn chỉnh với toán tử trải rộng, chúng ta sẽ phải viết một số mã bổ sung Xem xét cùng một đối tượng người dùng nhưng với một đối tượng lồng nhau 1 y = x // x is copied into y54 2 27 3 29 4___ let x = 382 52_______63 6 y = x // x is copied into y64 let x = 30 let x = 388 36 y = x // x is copied into y3 38 40 y = x // x is copied into y71 Để tránh làm thay đổi đối tượng ban đầu, đó là 342, chúng ta phải trải rộng đối tượng sao chép trước khi thực hiện các thay đổi trực tiếp đối với bất kỳ thuộc tính nào của nó. Đối với bất kỳ đối tượng lồng nhau nào, chúng ta cũng phải trải rộng đối tượng con đó trước khi thực hiện thay đổi đối với bất kỳ thuộc tính nào của nó 1 y = x // x is copied into y73_______2_______ y = x // x is copied into y75_______4__________ y = x // x is copied into y77 43_______79 53_______81 6___ y = x // x is copied into y83 let x = 30 y = x // x is copied into y85 36 y = x // x is copied into y3 Ở đây, chúng tôi đã biến đổi 360, là thuộc tính cấp cao nhất trong 344 và 361, là thuộc tính phụ Lần này, thao tác trải rộng sẽ tạo ra một bản sao sâu hoàn chỉnh trong đó đối tượng ban đầu sẽ không bị ảnh hưởng bởi bất kỳ đột biến nào trên bản sao ( 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 Sử dụng Lodash 341 để sao chép sâuLodash cũng cung cấp một phương thức tiện ích 371 để sao chép sâu các đối tượng trong JavaScript. Phần kết luậnNhư bạn đã thấy, có một số cách để sao chép một biến trong JavaScript. Không có phương pháp nào là hoàn hảo cho mọi trường hợp, vì vậy bạn sẽ phải cẩn thận để chọn phương pháp tốt nhất cho từng tình huống Làm cách nào để sao chép nông một mảng đối tượng trong JavaScript?Sao chép mảng nông bằng Array. Một phương pháp khác để sao chép mảng JavaScript là sử dụng Array. from() , cũng sẽ tạo một bản sao nông, như trong ví dụ này. Nếu một đối tượng hoặc mảng chứa các đối tượng hoặc mảng khác, các bản sao nông sẽ hoạt động ngoài dự kiến, bởi vì các đối tượng lồng nhau không thực sự được sao chép.
Làm cách nào để tạo bản sao sâu của đối tượng trong JavaScript?Bây giờ để tạo một bản sao sâu của một đối tượng trong JavaScript, chúng tôi sử dụng JSON. phân tích cú pháp () và JSON. các phương thức stringify() .
Làm cách nào để sao chép sâu đối tượng lồng nhau trong JavaScript?Để có được Bản sao sâu / bản sao của một đối tượng lồng nhau , chúng ta có thể sử dụng JSON. phân tích cú pháp (JSON. phương thức stringify()) .
Bản sao sâu của một mảng là gì?Bản sao sâu của đối tượng là bản sao có thuộc tính không chia sẻ cùng tham chiếu (trỏ đến cùng giá trị cơ bản) như thuộc tính của đối tượng nguồn mà từ đó bản sao được tạo ra . . |