Hướng dẫn deep copy array object javascript - sao chép sâu đối tượng mảng javascript

Tạo một bản sao sâu với cấu trúc

Cách hiện đại để sao chép sâu một mảng trong JavaScript là sử dụng StructuredClone:

array2 = structuredClone(array1);

Tuy nhiên, chức năng này tương đối mới (Chrome 98, Firefox 94) và hiện chỉ có sẵn cho khoảng 85% người dùng, vì vậy nó chưa sẵn sàng để sản xuất mà không có polyfill.

Thay vào đó, bạn có thể sử dụng một trong những giải pháp dựa trên JSON được hỗ trợ tốt dưới đây.

Tạo một bản sao sâu với JSON.Parse

Một giải pháp chung, có thể không thể thực hiện được tất cả các đối tượng có thể bên trong một mảng đối tượng. Điều đó nói rằng, nếu mảng của bạn chứa các đối tượng có nội dung JSON-serializable (không có chức năng, không Number.POSITIVE_INFINITY, v.v.) Một cách đơn giản để tránh các vòng lặp, với chi phí hiệu suất, là giải pháp một dòng vani thuần túy này.

let clonedArray = JSON.parse(JSON.stringify(nodesArray))

Để tóm tắt các ý kiến ​​dưới đây, lợi thế chính của phương pháp này là nó cũng sao chép nội dung của mảng, không chỉ là mảng. Các nhược điểm chính là giới hạn của nó chỉ hoạt động trên nội dung JSON-serializable và hiệu suất của nó chậm hơn ~ 30 lần so với phương pháp lan truyền.

Nếu bạn có các đối tượng nông trong mảng và IE6 có thể chấp nhận được, một cách tiếp cận tốt hơn là sử dụng toán tử lây lan kết hợp với toán tử mảng .map. Đối với hai cấp độ sâu sắc (như mảng trong Phụ lục bên dưới):

clonedArray = nodesArray.map(a => {return {...a}})

Các lý do là hai lần: 1) Nó nhanh hơn nhiều (xem bên dưới để so sánh điểm chuẩn) và nó cũng sẽ cho phép bất kỳ đối tượng hợp lệ nào trong mảng của bạn.

*Phụ lục: Định lượng hiệu suất dựa trên việc nhân bản mảng đối tượng này một triệu lần:

 [{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic1.jpg?raw=true', id: '1', isFavorite: false}, {url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic2.jpg?raw=true', id: '2', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic3.jpg?raw=true', id: '3', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic4.jpg?raw=true', id: '4', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic5.jpg?raw=true', id: '5', isFavorite: true},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic6.jpg?raw=true', id: '6', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic7.jpg?raw=true', id: '7', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic8.jpg?raw=true', id: '8', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic9.jpg?raw=true', id: '9', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic10.jpg?raw=true', id: '10', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic11.jpg?raw=true', id: '11', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic12.jpg?raw=true', id: '12', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic13.jpg?raw=true', id: '13', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic14.jpg?raw=true', id: '14', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic15.jpg?raw=true', id: '15', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic16.jpg?raw=true', id: '16', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic17.jpg?raw=true', id: '17', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic18.jpg?raw=true', id: '18', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic19.jpg?raw=true', id: '19', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic20.jpg?raw=true', id: '20', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic21.jpg?raw=true', id: '21', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic22.jpg?raw=true', id: '22', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic23.jpg?raw=true', id: '23', isFavorite: false}]

hoặc sử dụng:

let clonedArray = JSON.parse(JSON.stringify(nodesArray))

or:

clonedArray = nodesArray.map(a => {return {...a}})

Cách tiếp cận bản đồ/lan truyền đã mất 0,000466 ms mỗi lần và JSON.Parse và JSON.Stringify 0,014771 ms mỗi lần vượt qua.*

Mảng sao chép sâu trong JavaScript là gì?

Một bản sao sâu của một đối tượng là một bản sao có thuộc tính không chia sẻ cùng các tài liệu tham khảo (chỉ ra các giá trị cơ bản giống nhau) như của đối tượng nguồn mà bản sao được tạo.a copy whose properties do not share the same references (point to the same underlying values) as those of the source object from which the copy was made.

Bản sao mảng có phải là bản sao sâu không?

Một bản sao sâu có nghĩa là thực sự tạo ra một mảng mới và sao chép các giá trị.Mã trên cho thấy sao chép sâu.Các thay đổi đối với các giá trị mảng đề cập đến sẽ không dẫn đến các thay đổi đối với dữ liệu mảng đề cập đến.. The above code shows deep copying. Changes to the array values refers to will not result in changes to the array data refers to.

Đối tượng có lan truyền bản sao sâu không?

Toán tử lây lan tạo các bản sao sâu của dữ liệu nếu dữ liệu không được lồng.Khi bạn có dữ liệu lồng trong một mảng hoặc đối tượng, toán tử lan truyền sẽ tạo một bản sao sâu của hầu hết dữ liệu hàng đầu và một bản sao nông của dữ liệu lồng nhau.. When you have nested data in an array or object the spread operator will create a deep copy of the top most data and a shallow copy of the nested data.

JavaScript có lan truyền bản sao sâu không?

Đối với các đối tượng lồng nhau, toán tử lây lan sẽ cung cấp một bản sao sâu cho trường hợp đầu tiên của các giá trị nhưng để lại tất cả các dữ liệu lồng nhau dưới dạng các bản sao nông chia sẻ một không gian trong bộ nhớ với bản gốc.Hãy lưu ý về hành vi này!the spread operator will provide a deep copy to the first instance of the values but leaves all the nested data as shallow copies sharing a space in memory with original. Take note of this behavior!