planets-top
Published on

JavaScript truyền tham số theo kiểu tham chiếu hay theo kiểu tham trị?

Authors

Usage

Trong JavaScript, việc truyền tham số cho hàm có thể được coi là cả tham chiếu (pass by value) và tham trị (pass by reference), tùy thuộc vào kiểu dữ liệu của tham số được truyền vào.

Ví dụ, khi bạn truyền một biến kiểu nguyên thủy vào một hàm, một bản sao của giá trị được tạo ra và sử dụng trong hàm. Bất kỳ thay đổi nào đối với giá trị này trong hàm không ảnh hưởng đến biến gốc. Tuy nhiên, khi bạn truyền một đối tượng vào một hàm, tham chiếu đến đối tượng được truyền đi. Bất kỳ thay đổi nào đối với đối tượng trong hàm sẽ phản ánh trên đối tượng gốc.

1. Pass by Value (Truyền theo kiểu tham trị)

Dữ liệu nguyên thủy (primitive types) như number, string, boolean, null, undefind và sysmbol đều được truyền theo kiểu by pass value. Khi bạn truyền 1 giá trị nguyên thủy v trong hàm, không ảnh hưởng tới giá trị gốc bên ngoài.

Ví dụ:

function modifyValue(value) {
  value = 10
  console.log('Inside function', value) // Output: 10
}

let x = 5
modifyValue(x)
console.log('Outside function:', x) // Output: 5

Trong ví dụ này, giá trị của x bên ngoài hàm không thay đổi vì tham số được truyền theo kiểu tham trị.

2. Pass by Value (Truyền theo kiểu tham chiếu)

Đối tượng (objects) và mảng (arrays) được truyền theo kiểu pass by reference. Khi truyền một đối tượng hoặc mảng vào hàm, tham chiếu đến vùng nhớ của đối tượng/mảng đó sẽ được truyền vào, nghĩa là bất kỳ thay đổi nào trong hàm sẽ ảnh hưởng trực tiếp đến đối tượng/mảng ban đầu.

Ví dụ:

function modifyObject(obj) {
  obj.name = 'Alice'
  console.log('Inside function:', obj)
}

let person = { name: 'Bob' }
modifyObject(person)
console.log('Outside function:', person) // Output: { name: "Alice" }

Trong ví dụ này, đối tượng person bị thay đổi bên ngoài hàm vì hàm nhận tham chiếu đến đối tượng gốc và thay đổi trực tiếp thuộc tính của nó.

Sự khác biệt giữa pass by value và pass by reference

  • Pass by value: Khi truyền giá trị, hàm chỉ nhận một bản sao của giá trị đó và bất kỳ thay đổi nào đều không ảnh hưởng đến giá trị gốc.
  • Pass by reference: Khi truyền tham chiếu, hàm có thể thay đổi nội dung của đối tượng hoặc mảng gốc vì cả hàm và biến gốc đều tham chiếu đến cùng một vùng nhớ.

Một số lưu ý

  • Dù đối tượng và mảng được truyền theo kiểu tham chiếu, nếu bạn gán lại biến tham chiếu đó trong hàm, tham chiếu mới sẽ không ảnh hưởng đến biến ban đầu. Ví dụ:
function reassignArray(arr) {
  arr = [4, 5, 6] // Gán lại tham chiếu mới
  console.log('Inside function:', arr) // Output: [4, 5, 6]
}

let numbers = [1, 2, 3]
reassignArray(numbers)
console.log('Outside function:', numbers) // Output: [1, 2, 3]