01/10/2018, 10:06

Về object trong javascript

Chào mọi người, mình có thắc mắc về vấn đề sau. Hi vọng mọi người có thể giải đáp giúp ạ.

obj1 = {
ten: ‘Duong’,
tuoi: 18,
}
var obj2 = obj1;
obj1.tuoi = 30;

console.log(obj2);

Kết quả là: 30.
Tại sao lại như vậy ạ

Henry viết 12:14 ngày 01/10/2018

Có thể là var obj2 = obj1 khiến cho obj1obj2 cùng ở một vị trí vùng nhớ. Do đó khi thay của obj1 thì cũng gián tiếp thay obj2
Ví dụ như bạn có một xe mà bạn cho thằng bạn của bạn 2 đứa sài chung. Khi nó làm hỏng xe của nó cũng có nghĩa nó cũng làm hỏng xe của bạn

Nguyễn Dương viết 12:16 ngày 01/10/2018

hi bạn,
mình cũng nghĩ vậy. nhưng vấn đề là tại sao nó lại cho 2 thằng có cùng địa chỉ trong vùng nhớ

Henry viết 12:14 ngày 01/10/2018

Đơn giản mà vì bạn gán nó mà

var obj2 = obj1;

Như vậy bạn đã cho obj2obj1 cùng chạy một chiếc xe rồi
Có thể bạn nghĩ nó lấy giá trị của obj1 ra để gán cho ojb2 nhưng tiếc là nó không làm thế

Nguyễn Dương viết 12:07 ngày 01/10/2018

Nhưng nếu bạn lập trình C hay C++ thì nó khác
Ví dụ:
int i=6;
int d=i;
i++;
cout<<d : Kết quả là: 6

viết 12:16 ngày 01/10/2018

Mỗi ngôn ngữ có cách xử lý vùng nhớ khác nhau.
Việc bê nguyên lý của ngôn ngữ này sang ngôn ngữ kia và mong là nó làm việc giống nhau là điều hoàn toàn sai lầm.
Cái bạn cần làm là google “shadow copy javascript” ngta sẽ chỉ cho bạn biết cách để copy 1 object theo đúng chuẩn js

Henry viết 12:21 ngày 01/10/2018

Không bạn à Thật ra gán biến như vậy thì nó chỉ lấy giá trị thôi khôn tin bạn thử bên js xem nó cũng như C/C++ thôi. Quan trọng ở đây là bạn đang thao tác với object

rogp10 viết 12:14 ngày 01/10/2018

obj1 và obj2 suy cho cùng cũng chỉ là hai tham chiếu đến đối tượng chứ không phải chính đối tượng đó, gán khơi khơi thì nó vậy. Còn primitive thì gán vậy được do nó có trỏ đâu.

Nếu chuyển từ C/C++ qua thì nó khá giống con trỏ, do tham chiếu C++ chỉ bind 1 lần duy nhất và bind ngay từ đầu.

Thuc Nguyen Tan viết 12:08 ngày 01/10/2018

Ný luận làm gì cho cực vậy bạn! Bạn muốn copy phải không phải làm thế này mới ok

    var obj2=JSON.parse(JSON.stringify(obj1));
rogp10 viết 12:16 ngày 01/10/2018

Tại sao phải lấy JSON làm trung gian?

Nguyễn Hoàng viết 12:20 ngày 01/10/2018

lấy json làm trung gian thì nó sẽ tạo ra bản sao nhưng hoàn toàn riêng biệt với object ban đầu. gán bằng toán tử “=” thực chất chỉ là 2 biến cùng trỏ về một vùng nhớ

null viết 12:22 ngày 01/10/2018

Việc gán biến (variable) trong js

  • Nếu dữ liệu object (bao gồm array) thì nó chỉ tham chiếu đến.
  • Các dạng dữ liệu khác trừ function thì nó sẽ lưu lại giá trị.
    Mình tách function ra vì tùy thuộc vào cách bạn gán là hàm thực thi hay chưa, và giá trị được trả về, mà nó quay lại 2 kiểu trên.
    Tìm kiếm sâu hơn các khái niệm pass by valuepass by reference chỉ gây tranh cãi chứ không hoàn toàn giải thích được vấn đề.

Ný luận làm gì cho cực vậy bạn! Bạn muốn copy phải không phải làm thế này mới ok

var obj2=JSON.parse(JSON.stringify(obj1));

Trừ khi object của bạn hoàn toàn theo chuẩn json, nếu không cách này sẽ làm hỏng dữ liệu, và đây cũng là cách chậm nhất để tạo bản sao của object.

@Nguyen_Duong221 Nếu bạn muốn kế thừa lại mẫu thì OOJS là cái bạn cần. Nên xem thêm Working with objects .

Nguyễn Hoàng viết 12:21 ngày 01/10/2018
  • object thuần , array, function thì đều là objec cả.
  • không nên giải thích cái function thực thi hay chưa dễ gây hiểu sai vấn đề, function là function, là object. việc thực thi hay không không ảnh hưởng gì đến function đó. cái bạn nói là giá trị trả về của function là một vấn đề hoàn toàn không liên quan.
  • trong js không có khái niệm pass-by-reference, chỉ có khái niệm share by reference, khi gán một biến cho Primitive data thì nó sẽ copy giá trị đó, khi gán cho object thì nó sẽ copy reference của object đó, tất cả giá trị truyển vào function đều là pass value, với object thì value này là refernce trỏ tới object đó
null viết 12:11 ngày 01/10/2018

Mình giải thích theo typeof, vì nói object trong js thì cái gì cũng từ Object mà ra. Nếu nói thế dễ gây nhầm lẫn. Mình thấy chỉ cần tập trung vào đang gán cái gì. Ví dụ thế này:

var x = function() {
    console.log(1);
    return 2;
};

Nếu gán var y = x; thì console.log(y()); luôn ra 12.
Nếu gán var y = x(); thì console.log(y); lần đầu sẽ ra 12, các lần sau sẽ chỉ ra 2.

Còn các thuật ngữ kia thì mình không tìm thấy tài liệu chuẩn nào đề cập đến, lấy trong cách tranh luận trên stackoverflow và quora.

Thuc Nguyen Tan viết 12:06 ngày 01/10/2018
    Câu lệnh trên thực chất là làm thế này
obj2.ten=obj1.ten;
obj2.tuoi=obj1.tuoi;
 ....
 có 1 trăm cái chắc chết!!!!
Jo Ker viết 12:08 ngày 01/10/2018

Biến Object trong javascript là reference variable bạn ạ.
Đây là video giải thích rất hay về 2 loại biến reference và primitive trong javascript:


Nếu bạn muốn copy một object, có thể dùng Object.assign
VD var obj2 = Object.assign({}, obj1);
Tài liệu Web MDN

Object.assign()

Object.assign() được sử dụng để sao chép các giá trị của tất cả thuộc tính có thể liệt kê từ một hoặc nhiều đối tượng nguồn đến một đối tượng đích. Nó sẽ  trả về đối tượng đích đó.

Bài liên quan
0