TL;DR. KHÔNG có con trỏ trong JavaScript và các tham chiếu hoạt động khác với những gì chúng ta thường thấy trong hầu hết các ngôn ngữ lập trình phổ biến khác. Trong JavaScript, KHÔNG thể có tham chiếu từ biến này sang biến khác. Và, chỉ các giá trị phức hợp [e. g. Đối tượng hoặc Mảng] có thể được chỉ định theo tham chiếu
Các thuật ngữ sau đây được sử dụng trong suốt bài viết
- vô hướng – một giá trị hoặc đơn vị dữ liệu [e. g. số nguyên, boolean, chuỗi]
- hợp chất – bao gồm nhiều giá trị [e. g. mảng, đối tượng, tập hợp]
- nguyên thủy – một giá trị trực tiếp, trái ngược với một tham chiếu đến một cái gì đó có chứa giá trị thực
Các kiểu tham chiếu vô hướng của JavaScript là kiểu nguyên thủy, nhưng một số ngôn ngữ, chẳng hạn như Ruby, có các kiểu tham chiếu vô hướng. Lưu ý rằng trong JavaScript, các giá trị nguyên thủy vô hướng là bất biến trong khi các giá trị phức hợp có thể thay đổi
Bài viết này ban đầu được xuất bản trên Medium
Dòng dưới cùng về tài liệu tham khảo JavaScript
- Giá trị
4 được gán cho một biến quyết định liệu giá trị đó được lưu trữ với kiểu gán theo giá trị hay gán theo tham chiếuvar flash = [8,8,8]; var quicksilver = flash; //assign-by-reference quicksilver.push[0]; console.log[flash]; //[8,8,8,0] console.log[quicksilver]; //[8,8,8,0]
- Khi gán biến, các giá trị nguyên thủy vô hướng [Số, Chuỗi, Boolean, không xác định, null, Ký hiệu] được gán theo giá trị và các giá trị phức hợp được gán theo tham chiếu
- Các tham chiếu trong JavaScript chỉ trỏ vào các giá trị được chứa và KHÔNG nhắm vào các biến hoặc tham chiếu khác
- Trong JavaScript, các giá trị nguyên thủy vô hướng là bất biến và các giá trị phức hợp có thể thay đổi
Ví dụ nhanh về gán theo giá trị
Trong đoạn mã bên dưới, chúng tôi đang gán một giá trị nguyên thủy vô hướng [một số] cho một biến và do đó, việc gán theo giá trị được áp dụng ở đây. Đầu tiên, biến
var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
5 được khởi tạo và khi biến var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
6 được gán với giá trị được lưu trữ trong var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
5, nó sẽ tạo một bản sao mới của giá trị và lưu trữ nó. Khi biến var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
6 được sửa đổi, thì var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
5 không bị ảnh hưởng vì chúng trỏ đến các giá trị riêng biệtvar batman = 7;
var superman = batman; //assign-by-value
superman++;
console.log[batman]; //7
console.log[superman]; //8
Ví dụ nhanh về gán theo tham chiếu
Trong đoạn mã bên dưới, chúng tôi đang gán một giá trị phức hợp [một mảng] cho một biến và do đó, gán theo tham chiếu được áp dụng ở đây. Các biến
var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
3 và var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
4 là các tham chiếu đến cùng một giá trị [còn gọi là giá trị được chia sẻ]. Các tham chiếu sẽ trỏ đến giá trị được cập nhật khi giá trị được chia sẻ được sửa đổivar flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
Cách tạo một tham chiếu mới
Khi giá trị tổng hợp trong một biến được gán lại, một tham chiếu mới được tạo. Trong JavaScript, không giống như hầu hết các ngôn ngữ lập trình phổ biến khác, các tham chiếu là các con trỏ tới các giá trị được lưu trữ trong các biến và KHÔNG phải là các con trỏ tới các biến hoặc tham chiếu khác
var firestorm = [3,6,3];
var atom = firestorm; //assign-by-reference
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[3,6,3]
atom = [9,0,9]; //value is reassigned [create new reference]
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[9,0,9]
Cách tham chiếu hoạt động khi các giá trị được truyền dưới dạng tham số chức năng
Trong đoạn mã bên dưới, biến
var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
5 là một giá trị phức hợp [một Mảng], do đó nó được gán cho biến [đối số hàm] var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
6 làm tham chiếuPhương thức
var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
7 được gọi bên trong IIFE thay đổi giá trị trong biến var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
5 thông qua tham chiếu JavaScript. Tuy nhiên, việc gán lại biến var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
6 tạo ra một tham chiếu mới và các sửa đổi tiếp theo đối với nó KHÔNG ảnh hưởng đến tham chiếu đến biến var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
5var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
1Cách thay đổi giá trị gốc trong biến tổng hợp, được truyền dưới dạng đối số hàm thông qua tham chiếu JavaScript
Giải pháp ở đây là sửa đổi giá trị ghép hiện có mà tham chiếu đang trỏ tới. Trong đoạn mã bên dưới, biến
var firestorm = [3,6,3];
var atom = firestorm; //assign-by-reference
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[3,6,3]
atom = [9,0,9]; //value is reassigned [create new reference]
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[9,0,9]
1 là một giá trị phức hợp [một Mảng] và khi gọi IIFE, biến [đối số hàm] var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
6 được gán theo tham chiếuThuộc tính
var firestorm = [3,6,3];
var atom = firestorm; //assign-by-reference
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[3,6,3]
atom = [9,0,9]; //value is reassigned [create new reference]
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[9,0,9]
3 có thể được sử dụng để tạo một mảng trống bằng cách đặt giá trị của nó thành var firestorm = [3,6,3];
var atom = firestorm; //assign-by-reference
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[3,6,3]
atom = [9,0,9]; //value is reassigned [create new reference]
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[9,0,9]
4. Do đó, biến wolverine được thay đổi thành giá trị mới được đặt trong biến var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
6 thông qua tham chiếu JavaScriptvar flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
7Cách lưu trữ giá trị tổng hợp thông qua gán theo giá trị
Giải pháp ở đây là tạo một bản sao thủ công của giá trị ghép và sau đó gán giá trị đã sao chép cho một biến. Do đó, tham chiếu của giá trị được gán KHÔNG trỏ lại giá trị ban đầu
Cách tiếp cận được đề xuất để tạo một bản sao [nông] của giá trị phức hợp [đối tượng Array] là gọi phương thức
var firestorm = [3,6,3];
var atom = firestorm; //assign-by-reference
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[3,6,3]
atom = [9,0,9]; //value is reassigned [create new reference]
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[9,0,9]
6 trên đó mà không có đối số nào được truyềnvar flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
9Làm cách nào để lưu trữ giá trị nguyên thủy vô hướng thông qua gán theo tham chiếu?
Giải pháp ở đây là bọc giá trị nguyên thủy vô hướng trong một giá trị phức hợp [i. e. một Đối tượng hoặc Mảng] làm giá trị thuộc tính của nó. Do đó, nó có thể được chỉ định theo tham chiếu. Trong đoạn mã bên dưới, giá trị nguyên thủy vô hướng trong biến
var firestorm = [3,6,3];
var atom = firestorm; //assign-by-reference
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[3,6,3]
atom = [9,0,9]; //value is reassigned [create new reference]
console.log[firestorm]; //[3,6,3]
console.log[atom]; //[9,0,9]
7 được đặt làm thuộc tính trên đối tượng var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
3. Do đó, nó được gán theo tham chiếu khi gọi IIFE tới biến [đối số hàm] var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
6var flash = [8,8,8];
var quicksilver = flash; //assign-by-reference
quicksilver.push[0];
console.log[flash]; //[8,8,8,0]
console.log[quicksilver]; //[8,8,8,0]
3Tóm lược
Hiểu rõ về các tham chiếu trong JavaScript có thể giúp các nhà phát triển tránh được nhiều lỗi phổ biến và viết mã tốt hơn