2012-01-30 28 views
6

Ngay cả khi một nhà phát triển JS có phần nào đó tôi thấy mình liên tục bị bất ngờ ở các bản sao đối tượng nông và sâu.Có bất kỳ quy tắc nào khi các giá trị JavaScript được sao chép theo tham chiếu chứ không phải theo giá trị không?

Có bất kỳ quy tắc chung nào khi giá trị JavaScript được sao chép theo tham chiếu chứ không phải theo giá trị cho các loại đối tượng chính không? Ví dụ, tôi biết giá trị chuỗi luôn được sao chép bởi giá trị không tham chiếu.

+0

Phụ thuộc vào phương pháp sao chép của bạn. Bạn phải cụ thể - làm thế nào để bạn sao chép các giá trị của bạn? –

+0

Hay bạn có nghĩa là trường hợp khi một giá trị được chuyển như một đối số vào một hàm? –

+0

Thay vì được truyền qua các đối số, tôi đang nghĩ về một 'var x, y đơn giản; x = {'blah': 'foo'}; y = x; x = {'bar': 'bas'}; console.log (y); 'loại tình huống, nhưng nếu có nhiều sắc thái đối với các loại sao chép hơn xin vui lòng cho tôi biết cách tôi có thể cải thiện câu hỏi. – buley

Trả lời

4

Trong JavaScript, tất cả các đối tượng được lưu trữ và chuyển 'bằng tham chiếu'.

var a = { v: 'a' }, b = { v: 'b' }; 
a=b; 
b.v='c'; 

ab sẽ tham chiếu cùng một đối tượng; a.v == 'c'b.v == 'c'.

kiểu dữ liệu nguyên thủy (string, number, boolean, null, và undefined) là không thay đổi; chúng được truyền theo giá trị.

var a = 'a', b = 'b'; 
a=b; 
b='c'; 

Kể từ khi chúng tôi đang làm việc với nguyên thủy, a == 'b'b == 'c'.


pedants sẽ cho bạn biết rằng JavaScript được không pass-by-reference trong một cảm giác cổ điển, hoặc rằng đó là một "tinh khiết pass-by-value" ngôn ngữ, nhưng tôi nghĩ rằng những điều phức tạp cho các mục đích thực tế. Không, bạn không thể trực tiếp sửa đổi một đối số được chuyển đến một hàm như thể nó là một biến (điều này đúng nếu ngôn ngữ là đúng tham chiếu), nhưng bạn cũng không nhận được copy của một đối tượng được truyền dưới dạng một đối số (như bạn sẽ làm nếu nó là giá trị theo giá trị thực). Đối với hầu hết các mục đích (từ quan điểm của người dùng ngôn ngữ, bạn), các đối tượng được truyền cho một hàm là các tham chiếu, vì bạn có thể sửa đổi đối tượng đó và nó ảnh hưởng đến đối tượng của người gọi. Xem thêm fantastic answers to this question.

2

OK, hãy để tôi giải thích mã của bạn:

var x, y; 
x = { 'blah': 'foo' }; 
y = x; 
x = { 'bar': 'bas' }; 

Vì vậy, bạn khai báo hai biến, và sau đó bạn gán một giá trị đối tượng vào biến đầu tiên:

x = { 'blah': 'foo' }; 

Vì vậy, những gì xảy ra ở đây :

  1. Đối tượng theo nghĩa đen - { ... } - được đánh giá, dẫn đến việc tạo và khởi tạo đối tượng gốc mới.
  2. Một tham chiếu cho đối tượng này được gán cho biến x.

Tiếp theo, dòng này

y = x; 

chỉ sao chép tham chiếu được lưu trữ trong x vào biến y. Bây giờ cả hai biến lưu trữ cùng một tham chiếu đến đối tượng.

Cuối cùng, dòng này

x = { 'bar': 'bas' }; 

gán một giá trị mới cho biến x. Đối tượng theo nghĩa đen được đánh giá dẫn đến việc tạo/khởi tạo đối tượng khác và tham chiếu đến đối tượng đó được lưu trữ trong x.

Biến số y, tuy nhiên, vẫn giữ tham chiếu đến đối tượng đầu tiên.

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