Hướng dẫn which reference type value is accepted by javascript? - javascript chấp nhận giá trị kiểu tham chiếu nào?

Một cái nhìn đơn giản về bộ nhớ máy tính giải thích những gì xảy ra

Bài viết này đã được thực hiện từ Bước lên JS của bạn: Hướng dẫn toàn diện về JavaScript trung gian, khóa học trực tuyến của tôi. Hãy xem nó ở đó cho các sân chơi mã tương tác và một bài kiểm tra trực tuyến.

JavaScript có 5 loại dữ liệu được truyền theo giá trị:

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
7,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
8,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
9,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
0 và
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
1. Chúng tôi sẽ gọi các loại nguyên thủy này.value:
var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
7,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
8,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
9,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
0, and
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
1. We’ll call these primitive types.

JavaScript có 3 loại dữ liệu được truyền bằng tham chiếu:

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
2,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
3 và
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
4. Đây là tất cả các đối tượng về mặt kỹ thuật, vì vậy chúng tôi sẽ gọi chúng là đối tượng.reference:
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
2,
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
3, and
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
4. These are all technically Objects, so we’ll refer to them collectively as Objects.

Nguyên thủy

Nếu một loại nguyên thủy được gán cho một biến, chúng ta có thể nghĩ về biến đó là chứa giá trị nguyên thủy.

var x = 10;
var y = 'abc';
var z = null;

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
5 chứa
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
6.
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
7 chứa
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
8. Để củng cố ý tưởng này, chúng tôi sẽ duy trì một hình ảnh về những biến này và các giá trị tương ứng của chúng trông giống như trong bộ nhớ.

Khi chúng tôi gán các biến này cho các biến khác bằng cách sử dụng

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
9, chúng tôi sao chép giá trị vào biến mới. Chúng được sao chép bởi giá trị.copy the value to the new variable. They are copied by value.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'

Cả

1) var arr = [];
2) arr.push(1);
0 và
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
5 hiện đều chứa
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
6. Cả
1) var arr = [];
2) arr.push(1);
3 và
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
7 hiện đều chứa
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
8. Họ tách biệt, vì các giá trị đã được sao chép.

Thay đổi cái này không thay đổi cái kia. Hãy nghĩ về các biến là không có mối quan hệ với nhau.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'

Các đối tượng

Điều này sẽ cảm thấy khó hiểu, nhưng hãy chịu đựng tôi và đọc qua nó. Một khi bạn vượt qua nó, nó sẽ có vẻ dễ dàng.

Các biến được gán một giá trị không nguyên thủy được cung cấp một tham chiếu đến giá trị đó. Tham chiếu đó trỏ đến vị trí đối tượng trong bộ nhớ. Các biến không thực sự chứa giá trị.

Các đối tượng được tạo tại một số vị trí trong bộ nhớ máy tính của bạn. Khi chúng tôi viết

1) var arr = [];
2) arr.push(1);
6, chúng tôi đã tạo ra một mảng trong bộ nhớ. Những gì biến
1) var arr = [];
2) arr.push(1);
7 nhận được là địa chỉ, vị trí, của mảng đó.

Hãy cùng giả vờ rằng

1) var arr = [];
2) arr.push(1);
8 là một loại dữ liệu mới được truyền theo giá trị, giống như
1) var arr = [];
2) arr.push(1);
9 hoặc
var reference = [1];
var refCopy = reference;
0. Một
1) var arr = [];
2) arr.push(1);
8 chỉ vào vị trí, trong bộ nhớ, có giá trị được truyền bằng tham chiếu. Giống như một chuỗi được biểu thị bằng dấu ngoặc kép (
var reference = [1];
var refCopy = reference;
2 hoặc
var reference = [1];
var refCopy = reference;
3), một
1) var arr = [];
2) arr.push(1);
8 sẽ được ký hiệu bằng dấu ngoặc mũi tên,
var reference = [1];
var refCopy = reference;
5.

Khi chúng tôi gán và sử dụng biến loại tham chiếu, những gì chúng tôi viết và xem là:

1) var arr = [];
2) arr.push(1);

Một đại diện của các dòng 1 và 2 ở trên trong bộ nhớ là:

1.

2.

Lưu ý rằng giá trị, địa chỉ, được chứa bởi biến

1) var arr = [];
2) arr.push(1);
7 là tĩnh. Mảng trong bộ nhớ là những gì thay đổi. Khi chúng tôi sử dụng
1) var arr = [];
2) arr.push(1);
7 để làm một cái gì đó, chẳng hạn như đẩy giá trị, công cụ JavaScript đi đến vị trí của
1) var arr = [];
2) arr.push(1);
7 trong bộ nhớ và hoạt động với thông tin được lưu trữ ở đó.

Gán bằng tham chiếu

Khi một giá trị loại tham chiếu, một đối tượng, được sao chép vào một biến khác bằng cách sử dụng

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
9, địa chỉ của giá trị đó là những gì mà thực sự đã sao chép như thể nó là nguyên thủy. Các đối tượng được sao chép bằng tham chiếu thay vì theo giá trị. Objects are copied by reference instead of by value.

var reference = [1];
var refCopy = reference;

Mã trên trông như thế này trong bộ nhớ.

Mỗi biến hiện chứa một tham chiếu đến cùng một mảng. Điều đó có nghĩa là nếu chúng ta thay đổi

reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
0,
reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
1 sẽ thấy những thay đổi đó:

reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]

Chúng tôi đã đẩy

reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
2 vào mảng trong bộ nhớ. Khi chúng tôi sử dụng
reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
0 và
reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
1, chúng tôi sẽ chỉ vào cùng một mảng đó.

Chỉ định lại một tài liệu tham khảo

Việc công bố lại một biến tham chiếu thay thế tham chiếu cũ.

var obj = { first: 'reference' };

Trong trí nhớ:

Khi chúng ta có dòng thứ hai:

var obj = { first: 'reference' };
obj = { second: 'ref2' }

Địa chỉ được lưu trữ trong

reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
5 thay đổi. Đối tượng đầu tiên vẫn còn trong bộ nhớ và đối tượng tiếp theo cũng vậy:

Khi không có tham chiếu đến một đối tượng còn lại, như chúng ta thấy địa chỉ

reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
6 ở trên, động cơ JavaScript có thể thực hiện bộ sưu tập rác. Điều này chỉ có nghĩa là lập trình viên đã mất tất cả các tham chiếu đến đối tượng và có thể sử dụng đối tượng nữa, vì vậy động cơ có thể tiếp tục và xóa nó một cách an toàn khỏi bộ nhớ. Trong trường hợp này, đối tượng
reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
7 không còn có thể truy cập được và có sẵn cho động cơ để thu gom rác.

== và ===

Khi các toán tử bình đẳng,

reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
8 và
reference.push(2);
console.log(reference, refCopy); // -> [1, 2], [1, 2]
9, được sử dụng trên các biến loại tham chiếu, họ sẽ kiểm tra tham chiếu. Nếu các biến chứa một tham chiếu đến cùng một mục, so sánh sẽ dẫn đến
var obj = { first: 'reference' };
0.

var arrRef = [’Hi!’];
var arrRef2 = arrRef;
console.log(arrRef === arrRef2); // -> true

Nếu chúng là các đối tượng riêng biệt, ngay cả khi chúng chứa các thuộc tính giống hệt nhau, so sánh sẽ dẫn đến

var obj = { first: 'reference' };
1.

var arr1 = ['Hi!'];
var arr2 = ['Hi!'];
console.log(arr1 === arr2); // -> false

Nếu chúng ta có hai đối tượng riêng biệt và muốn xem liệu thuộc tính của chúng có giống nhau hay không, cách dễ nhất để làm như vậy là biến chúng thành cả hai chuỗi và sau đó so sánh các chuỗi. Khi các toán tử bình đẳng đang so sánh các nguyên thủy, họ chỉ cần kiểm tra xem các giá trị có giống nhau không.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
0

Một tùy chọn khác sẽ là vòng lặp đệ quy thông qua các đối tượng và đảm bảo mỗi thuộc tính là như nhau.

Truyền các tham số thông qua các chức năng

Khi chúng ta chuyển các giá trị nguyên thủy vào một hàm, hàm sao chép các giá trị vào các tham số của nó. Nó có hiệu quả giống như sử dụng

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
9.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
1

Trong ví dụ trên, chúng tôi cung cấp cho

var obj = { first: 'reference' };
3 giá trị
var obj = { first: 'reference' };
4. Khi chúng tôi chuyển nó vào
var obj = { first: 'reference' };
5, biến
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
5 sẽ nhận được giá trị đó,
var obj = { first: 'reference' };
4. Giá trị được sao chép qua như thể chúng ta đã sử dụng gán
var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
9. Một lần nữa, giá trị của
var obj = { first: 'reference' };
3 không bị ảnh hưởng. Dưới đây là ảnh chụp nhanh về bộ nhớ trông như thế nào tại dòng bình luận tạm dừng trong
var obj = { first: 'reference' };
5.

Chức năng thuần túy

Chúng tôi đề cập đến các chức năng don don ảnh hưởng đến bất cứ điều gì trong phạm vi bên ngoài là các chức năng thuần túy. Miễn là một hàm chỉ có các giá trị nguyên thủy làm tham số và không sử dụng bất kỳ biến nào trong phạm vi xung quanh của nó, nó tự động tinh khiết, vì nó có thể ảnh hưởng đến bất cứ điều gì trong phạm vi bên ngoài. Tất cả các biến được tạo bên trong đều được thu thập rác ngay khi hàm trả về.

Tuy nhiên, một chức năng có trong một đối tượng có thể biến đổi trạng thái của phạm vi xung quanh. Nếu một hàm có trong một tham chiếu mảng và thay đổi mảng mà nó chỉ vào, có lẽ bằng cách đẩy vào nó, các biến trong phạm vi xung quanh tham chiếu mảng thấy sự thay đổi đó. Sau khi hàm trở lại, những thay đổi mà nó vẫn tồn tại trong phạm vi bên ngoài. Điều này có thể gây ra các tác dụng phụ không mong muốn có thể khó theo dõi.

Do đó, nhiều hàm mảng gốc, bao gồm

var obj = { first: 'reference' };
obj = { second: 'ref2' }
1 và
var obj = { first: 'reference' };
obj = { second: 'ref2' }
2, được viết dưới dạng các hàm thuần túy. Họ lấy một tham chiếu mảng và bên trong, họ sao chép mảng và làm việc với bản sao thay vì bản gốc. Điều này làm cho nó để bản gốc không bị ảnh hưởng, phạm vi bên ngoài không bị ảnh hưởng và chúng tôi đã trả lại một tài liệu tham khảo cho một mảng hoàn toàn mới.

Hãy cùng đi vào một ví dụ về chức năng thuần khiết so với không trong sạch.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
2

Hàm không tinh khiết này có trong một đối tượng và thay đổi thuộc tính

var obj = { first: 'reference' };
obj = { second: 'ref2' }
3 trên đối tượng đó là 25. Bởi vì nó hoạt động trên tham chiếu mà nó được đưa ra, nó thay đổi trực tiếp đối tượng
var obj = { first: 'reference' };
obj = { second: 'ref2' }
4. Lưu ý rằng khi nó trả về đối tượng
var obj = { first: 'reference' };
obj = { second: 'ref2' }
5, nó sẽ trả về cùng một đối tượng được truyền vào.
var obj = { first: 'reference' };
obj = { second: 'ref2' }
4 và
var obj = { first: 'reference' };
obj = { second: 'ref2' }
7 chứa cùng một tham chiếu. Nó dự phòng để trả về biến
var obj = { first: 'reference' };
obj = { second: 'ref2' }
5 và lưu trữ tham chiếu trong một biến mới.

Hãy cùng nhìn vào một chức năng thuần túy.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
3

Trong chức năng này, chúng tôi sử dụng

var obj = { first: 'reference' };
obj = { second: 'ref2' }
9 để chuyển đổi đối tượng mà chúng tôi đã truyền thành một chuỗi và sau đó phân tích lại nó thành một đối tượng với
var arrRef = [’Hi!’];
var arrRef2 = arrRef;
console.log(arrRef === arrRef2); // -> true
0. Bằng cách thực hiện chuyển đổi này và lưu trữ kết quả trong một biến mới, chúng tôi đã tạo ra một đối tượng mới. Có nhiều cách khác để làm điều tương tự như lặp qua đối tượng gốc và gán từng thuộc tính của nó cho một đối tượng mới, nhưng theo cách này là đơn giản nhất. Đối tượng mới có các thuộc tính giống như bản gốc nhưng nó là một đối tượng riêng biệt rõ ràng trong bộ nhớ.

Khi chúng tôi thay đổi thuộc tính

var obj = { first: 'reference' };
obj = { second: 'ref2' }
3 trên đối tượng mới này, bản gốc không bị ảnh hưởng. Chức năng này bây giờ là tinh khiết. Nó không thể ảnh hưởng đến bất kỳ đối tượng nào ngoài phạm vi của chính nó, thậm chí không phải đối tượng được truyền vào. Đối tượng mới cần được trả về và lưu trữ trong một biến mới hoặc nếu không nó được thu thập rác sau khi hàm hoàn thành, vì đối tượng không dài hơn trong phạm vi.

Tự kiểm tra

Giá trị so với tham chiếu là một khái niệm thường được thử nghiệm trong các cuộc phỏng vấn mã hóa. Cố gắng tìm ra những gì mà những gì mà đã đăng nhập ở đây.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
4

Hàm trước tiên thay đổi thuộc tính

var obj = { first: 'reference' };
obj = { second: 'ref2' }
3 trên đối tượng gốc mà nó được chuyển vào. Sau đó, nó chỉ định biến biến thành một đối tượng hoàn toàn mới và trả về đối tượng đó. Ở đây, những gì hai đối tượng được đăng xuất.

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
5

Hãy nhớ rằng việc gán thông qua các tham số chức năng về cơ bản giống như gán với

var x = 10;
var y = 'abc';
var a = x;
var b = y;
a = 5;
b = 'def';
console.log(x, y, a, b); // -> 10, 'abc', 5, 'def'
9. Biến
var obj = { first: 'reference' };
obj = { second: 'ref2' }
5 trong hàm chứa tham chiếu đến đối tượng
var arrRef = [’Hi!’];
var arrRef2 = arrRef;
console.log(arrRef === arrRef2); // -> true
5, do đó, ban đầu nó hoạt động trực tiếp trên đối tượng đó. Khi chúng tôi phân công lại
var obj = { first: 'reference' };
obj = { second: 'ref2' }
5 cho một đối tượng mới, nó sẽ ngừng ảnh hưởng đến bản gốc.

Việc xác định lại này không thay đổi đối tượng mà

var arrRef = [’Hi!’];
var arrRef2 = arrRef;
console.log(arrRef === arrRef2); // -> true
5 chỉ vào phạm vi bên ngoài.
var obj = { first: 'reference' };
obj = { second: 'ref2' }
5 có một tài liệu tham khảo mới vì nó đã được chỉ định lại nhưng sự phân công lại không thay đổi
var arrRef = [’Hi!’];
var arrRef2 = arrRef;
console.log(arrRef === arrRef2); // -> true
5.

Một đoạn mã tương đương với khối trên sẽ là:

var x = 10;
var y = 'abc';
var a = x;
var b = y;
console.log(x, y, a, b); // -> 10, 'abc', 10, 'abc'
6

Sự khác biệt duy nhất là khi chúng ta sử dụng hàm,

var obj = { first: 'reference' };
obj = { second: 'ref2' }
5 không còn phạm vi nữa khi hàm kết thúc.

Đó là nó. Đi viết một số mã.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Nếu điều này hữu ích, xin vui lòng đánh trái tim và cảm thấy thoải mái khi kiểm tra công việc khác của tôi.

Công việc của tôi

Khóa học trực tuyến

Tôi đã tạo ra một khóa học trực tuyến về giáo dục.

Bài viết gần đây

Loại tham chiếu trong JavaScript là gì?

Các loại dữ liệu tham chiếu, không giống như các loại dữ liệu nguyên thủy, có bản chất động.Đó là, họ không có kích thước cố định.Hầu hết chúng được coi là đối tượng, và do đó có các phương pháp.Ví dụ về các loại dữ liệu đó bao gồm mảng, chức năng, bộ sưu tập và tất cả các loại đối tượng khác.dynamic in nature. That is, they do not have a fixed size. Most of them are considered as objects, and therefore have methods. Examples of such data types include arrays, functions, collections, and all other types of objects.

Những giá trị nào được truyền bằng tham chiếu trong JavaScript?

Các loại dữ liệu nguyên thủy như chuỗi, số, null, không xác định, boolean, được truyền theo giá trị trong khi các loại dữ liệu không nguyên thủy như đối tượng, mảng và chức năng được truyền bằng cách tham chiếu trong JavaScript.objects, arrays, and functions are passed by reference in Javascript.

Loại dữ liệu nào là hợp lệ trong JavaScript?

Trong JavaScript, có năm loại dữ liệu cơ bản hoặc nguyên thủy.Năm loại dữ liệu cơ bản nhất là chuỗi, số, booleans, không xác định và null.strings, numbers, booleans, undefined, and null.

Là loại tham chiếu chuỗi trong JavaScript?

Chuỗi là một loại tham chiếu đặc biệt hoạt động giống như một loại giá trị trong toán tử bình đẳng.Khi một chuỗi được chuyển đến một hàm, tham chiếu của nó được chuyển đến hàm không phải là bản sao của giá trị của nó. that acts like a value type in equality operator. When a string is passed to a function, its reference is passed to the function not a copy of its value.