2015-05-30 16 views
8

Khi mảng được gán cho một biến khác, tham chiếu được truyền ngược với giá trị. Đây là khẳng định khi bạn so sánh hai mảng sử dụng == điều hành và nó trả trueTôi thiếu gì với sự hiểu biết về mảng?

var a = [[1,2],[3,4],[5,6]]; 
var b = a; // b = [[1,2],[3,4],[5,6]] 
var c = [].concat(a); // c = [[1,2],[3,4],[5,6]] 

a == b; //true 
a == c; //false 

Với đầu vào ở trên, khi tôi thay đổi mảng b, nó đột biến mảng a, nhưng không c.

b.push([7,8]); // b = [[1,2],[3,4],[5,6], [7,8]] 
a; //a = [[1,2],[3,4],[5,6], [7,8]] 
c; //c = [[1,2],[3,4],[5,6]] 

Nhưng khi tôi làm như dưới đây, nó sẽ biến đổi c.

b[0].push(5); // b = [[1,2,5],[3,4],[5,6], [7,8]] 
a; //a = [[1,2,5],[3,4],[5,6], [7,8]] 
c; //c = [[1,2,5],[3,4],[5,6]] 

Tại sao điều này xảy ra? Hành vi này xảy ra với việc sử dụng các phương thức mảng làm biến đổi mảng.

Trả lời

14

.concat() có bản sao nông. Vì vậy, sau khi dòng:

var c = [].concat(a); 

ca tham khảo các mảng khác nhau, nhưng c[0]b[0]a[0] tất cả các tham chiếu đến cùng một mảng.

Trích dẫn từ MDN:

concat bản sao đối tượng tài liệu tham khảo vào mảng mới. Cả mảng ban đầu và mảng mới đều tham chiếu đến cùng một đối tượng. Nghĩa là, nếu một đối tượng được tham chiếu được sửa đổi, các thay đổi sẽ hiển thị cho cả mảng mới và mảng ban đầu.

+0

+1, đó là câu trả lời. Bạn có nghĩ rằng nó sẽ là tốt để bao gồm làm thế nào để làm cho * sâu * bản sao của một mảng (hoặc bất kỳ đối tượng khác)? (jQuery '.extend()' hoặc lodash '.deepClone()'?) – bardzusny

+1

@bardzusny có rất nhiều câu trả lời trên stackoverflow rồi. – Leo

+0

thanks nnnnnn, giải thích hành vi. Như @bardzusny đã thêm vào, ai đó có thể đề xuất bất kỳ phương thức hoặc thư viện được xây dựng nào có bản sao sâu của mảng không? – Harish

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