Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Pass by Value vs Pass by Reference trong JavaScript

JavaScript luôn truyền tham số bằng giá trị (pass by value). Tuy nhiên, hành vi khác nhau giữa kiểu nguyên thủy (primitive) và kiểu tham chiếu (object/array).

1. Pass by Value (Kiểu nguyên thủy)

Với string, number, boolean, null, undefined, symbol, bigint: giá trị được sao chép. Thay đổi bên trong hàm không ảnh hưởng biến ngoài.

Ví dụ

<script>
  let a = 1;
  function thayDoi(val) {
    val = 2; // Chỉ thay đổi bản sao cục bộ
  }
  thayDoi(a);
  document.write(a); // 1 — không đổi
</script>

2. "Pass by Reference" giả vờ (Object/Array)

Với object/array: giá trị truyền đi là tham chiếu (địa chỉ bộ nhớ) — nhưng bản thân tham chiếu được truyền bằng giá trị. Do đó:

  • Mutation (đổi nội dung): Ảnh hưởng object gốc.
  • Reassignment (gán lại): Không ảnh hưởng object gốc.

Ví dụ Mutation — Ảnh hưởng gốc

<script>
  let obj = { num: 1 };
  function mut(val) {
    val.num = 2; // Thay đổi property của object gốc
  }
  mut(obj);
  document.write(JSON.stringify(obj)); // {"num":2}
</script>

Ví dụ Reassignment — KHÔNG ảnh hưởng gốc

<script>
  let obj = { num: 1 };
  function reassign(val) {
    val = { num: 2 }; // Tạo object mới, gán cho biến cục bộ val
  }
  reassign(obj);
  document.write(JSON.stringify(obj)); // {"num":1} — không đổi
</script>

Tóm tắt trực quan

Hành độngPrimitiveObject/Array
Gán lại tham số (param = ...)Không ảnh hưởng gốcKhông ảnh hưởng gốc
Thay đổi property/element (prop = ...)Không áp dụngẢnh hưởng gốc

Mẹo: Tạo bản sao thật sự (Deep Clone)

// Shallow clone
const copy1 = { ...original };
const copy2 = Object.assign({}, original);

// Deep clone (hạn chế: không hỗ trợ function, Date, RegExp, circular ref)
const deep = JSON.parse(JSON.stringify(original));