👋 Chào mừng đến với Blog - Thành Nam Nguyễn

Tham chiếu và tham trị trong JavaScript

Tham chiếu và tham trị trong JavaScript

Front-end

Có bao giờ bạn tự hỏi tại sao khi bạn thay đổi giá trị trong JavaScript nhưng lại không như mong đợi?

Trong bài viết này, chúng ta sẽ cùng tìm hiểu về hai khái niệm quan trọng trong JavaScript: tham chiếu (reference) và tham trị (value). Chúng ta sẽ xem xét cách chúng hoạt động, sự khác biệt giữa chúng, và cách sử dụng chúng đúng cách trong code của bạn.

1. Tham trị là gì?

Trong JavaScript, các giá trị nguyên thủy như số (number), chuỗi (string), boolean, null, và undefined được gọi là giá trị tham trị (pass by value). Điều này có nghĩa là khi bạn gán một biến với một giá trị nguyên thủy, giá trị này sẽ được sao chép và bất kỳ thay đổi nào đối với giá trị mới sẽ không ảnh hưởng đến giá trị ban đầu.

Ví dụ:

let a = 5;
let b = a;

b = 10;

console.log(a); // Kết quả: 5
console.log(b); // Kết quả: 10

Trong ví dụ trên, ab là hai biến độc lập nhau mặc dù chúng có cùng giá trị ban đầu. Khi thay đổi giá trị của b, a không bị ảnh hưởng.

2. Tham chiếu là gì?

Ngược lại với tham trị, tham chiếu áp dụng cho các đối tượng như object, array, và function. Khi bạn gán một biến với một đối tượng, biến đó sẽ lưu trữ một tham chiếu đến đối tượng trong bộ nhớ. Điều này có nghĩa là nếu bạn thay đổi đối tượng qua một biến, mọi biến khác tham chiếu đến đối tượng đó sẽ thấy sự thay đổi này.

Ví dụ:

let obj1 = { name: 'John' };
let obj2 = obj1;

obj2.name = 'Jane';

console.log(obj1.name); // Kết quả: Jane
console.log(obj2.name); // Kết quả: Jane

Trong ví dụ trên, obj1obj2 cùng tham chiếu đến cùng một đối tượng. Vì vậy, khi bạn thay đổi thuộc tính name của obj2, thuộc tính name của obj1 cũng thay đổi.

3. Sự khác biệt giữa tham chiếu và tham trị

Để hiểu rõ hơn sự khác biệt giữa tham chiếu và tham trị, hãy xem bảng so sánh dưới đây:

Tham trị (Pass by Value)Tham chiếu (Pass by Reference)
Kiểu dữ liệuSố, chuỗi, boolean, null, undefinedĐối tượng, mảng, hàm
Cách gán giá trịSao chép giá trị thực tếSao chép tham chiếu (địa chỉ) của đối tượng
Ảnh hưởng của thay đổiThay đổi biến không ảnh hưởng đến biến gốcThay đổi đối tượng ảnh hưởng đến tất cả các biến tham chiếu
Sao chép giá trịTạo một bản sao độc lậpTạo một liên kết đến cùng một đối tượng
Tối ưu bộ nhớKhông, mỗi biến giữ một giá trị riêngCó, nhiều biến có thể tham chiếu cùng một đối tượng

4. Các trường hợp sử dụng trong thực tế

Sử dụng tham trị

  • Khi bạn cần tạo ra các biến độc lập.

  • Khi bạn làm việc với các giá trị nguyên thủy và không muốn thay đổi chúng thông qua các biến khác.

Ví dụ:

function increment(num) {
  num++;
  return num;
}

let value = 5;
let newValue = increment(value);

console.log(value); // Kết quả: 5
console.log(newValue); // Kết quả: 6

Trong ví dụ này, num là một giá trị nguyên thủy và được truyền theo tham trị. Thay đổi num bên trong hàm không ảnh hưởng đến value.

Sử dụng tham chiếu

  • Khi bạn cần làm việc với các đối tượng và muốn các thay đổi được ảnh hưởng khắp các nơi khác.

  • Khi bạn muốn tránh việc sao chép các đối tượng lớn để tiết kiệm bộ nhớ.

Ví dụ:

function addProperty(obj) {
  obj.newProp = 'new';
}

let myObj = { prop: 'old' };
addProperty(myObj);

console.log(myObj); // Kết quả: { prop: 'old', newProp: 'new' }

Trong ví dụ này, myObj là một đối tượng và được truyền theo tham chiếu. Thay đổi obj bên trong hàm sẽ ảnh hưởng đến myObj.

❗️ Chú ý:

  • Hiểu rõ khi nào dùng tham chiếu và khi nào dùng tham trị: Việc này sẽ giúp bạn tránh được các lỗi không mong muốn và tối ưu hóa mã nguồn của mình.

  • Cẩn thận khi làm việc với các đối tượng: Do chúng được truyền theo tham chiếu, hãy chắc chắn rằng các thay đổi là cần thiết và không gây ra lỗi logic.

  • Sử dụng các kỹ thuật sao chép đối tượng nếu cần: Nếu bạn muốn tạo ra một bản sao của một đối tượng mà không làm ảnh hưởng đến đối tượng gốc, bạn có thể sử dụng các phương pháp như Object.assign hoặc các thư viện như lodash.

Hi vọng qua bài viết này, bạn đã có cái nhìn rõ ràng hơn về sự khác biệt giữa tham chiếu và tham trị trong JavaScript. Hiểu rõ hai khái niệm này sẽ giúp bạn viết code hiệu quả hơn và tránh được nhiều lỗi phổ biến.