2014-07-01 11 views
10

Theo tài liệu MDN, hãy gọi array.slice() sẽ tạo bản sao nông của mảng.Sự khác biệt giữa bản sao nông và bản sao sâu với các mảng JavaScript là gì?

Xem điều này MDN link for slice().

Tuy nhiên, nếu tôi chạy một thử nghiệm đơn giản như vậy trong giao diện điều khiển:

var test = [[1,2,3],7,8,9]; 
var shallow_copy = test.slice(); 

và kiểm tra shallow_copy, tôi có thể thấy rằng toàn bộ 2 mảng chiều dường như được sao chép.

Sự khác nhau giữa bản sao nông và bản sao sâu? Nếu tôi đoán, tôi sẽ gọi đây là một bản sao sâu.

+0

Nó có nghĩa là 'test [0] === shallow_copy [0]', chúng tham chiếu đến cùng một đối tượng mảng. – Bergi

+0

Tôi thấy việc sử dụng từ 'nông' và 'sâu' hoàn toàn khó hiểu trong tài liệu JavaScript vì nó đã được nói rằng các đối tượng không bao giờ được sao chép. Khi nó rõ ràng đọc 'nông' tôi mong đợi tất cả các yếu tố được tham chiếu đến cùng một điều (bao gồm cả các đối tượng không như số), nhưng nó chỉ áp dụng cho các đối tượng, đã được tuyên bố không bao giờ được sao chép. – destoryer

Trả lời

19

Để thấy sự khác biệt, hãy thử:

shallow_copy[0][2] = 4; 
console.dir(test); 

Bạn sẽ thấy rằng test đã được sửa đổi! Điều này là do trong khi bạn có thể đã sao chép các giá trị vào mảng mới, mảng lồng nhau vẫn là một mảng giống nhau.

Bản sao sâu sẽ đệ quy đệ quy các bản sao nông cho đến khi mọi thứ đều là bản sao mới của bản gốc.

2

Về cơ bản, bạn chỉ nhận được tham chiếu đến biến/mảng ban đầu. Thay đổi tham chiếu cũng sẽ thay đổi mảng ban đầu. Bạn cần lặp lại các giá trị của mảng ban đầu và tạo một bản sao.

Hãy xem xét ví dụ sau:

var orig = { a: 'A', b: 'B', c: 'C' }; 

Hãy nói rằng bạn muốn tạo một bản sao của này, do đó ngay cả khi bạn thay đổi các giá trị ban đầu, bạn luôn có thể quay trở lại với bản gốc.

tôi có thể làm điều này:

var dup = orig; //Shallow copy! 

Nếu chúng ta thay đổi một giá trị:

dup.a = 'Apple'; 

Tuyên bố này cũng sẽ thay đổi a từ orig, vì chúng ta có một bản sao cạn, hoặc một tham chiếu đến var orig. Điều này có nghĩa là bạn cũng đang mất dữ liệu gốc.

Tuy nhiên, việc tạo biến hoàn toàn mới bằng cách sử dụng các thuộc tính từ biến số orig gốc, bạn có thể tạo bản sao sâu.

var dup = { a: orig.a, b: orig.b, c: orig.c }; //Deep copy! 

Bây giờ nếu bạn thay đổi dup.a, nó sẽ chỉ ảnh hưởng đến dup và không orig.

+4

Đó không phải là bản sao nông. Đó không phải là một bản sao cả. –

+0

Tôi có thể sai, vui lòng sửa lỗi! Đây là những gì tôi học được từ một kinh nghiệm cũ. –

+1

Đây chỉ là truyền tham chiếu không phải bản sao nông hoặc sâu. Xem câu trả lời hay nhất tại: http://stackoverflow.com/questions/184710/what-is-the-difference-between-a-deep-copy-and-a-shallow-copy cho sự khác biệt giữa bản sao nông và sâu . Ngoài ra những gì bạn gọi là "bản sao sâu" trong ví dụ của bạn thực sự là một nông – elachell

Các vấn đề liên quan