Pass by value và Pass by reference là gì? | Tham trị và tham chiếu là gì?
Khi làm việc với ngôn ngữ lập trình, việc hiểu cách thức truyền tham số vào hàm là điều cần thiết để tránh lỗi khi thao tác với dữ liệu. Hai khái niệm thường gặp khi nói về việc truyền tham số là Pass by Value (Truyền theo giá trị) và Pass by Reference (Truyền theo tham chiếu). Vậy trong JavaScript, chúng hoạt động như thế nào? Bài viết này sẽ giúp bạn hiểu rõ hơn về hai khái niệm này và cách mà JavaScript thực sự xử lý chúng.
🥇 Pass by Value (Truyền theo giá trị)
Đặc điểm: Gán lại tham số trong hàm, không làm thay đổi biến bên ngoài hàm
Chúng ta xem xét ví dụ
Trong ví dụ này, quá trình xử lý diễn ra như sau:
-
Khi khai báo
x = 10
, JavaScript cấp phát vùng nhớ cho biếnx
trong Stack -
Khi gọi
changeValue(x)
, giá trị củax
sẽ được sao chép và truyền vào hàm, tạo thành tham sốy
. Lúc này, javascript sẽ cấp phát vùng nhớ khác cho y với giá trị sao chép từx
là 10 -
Sau đó, bên trong hàm
changeValue
,y
được gán lại là 20, nó chỉ sửa trong vùng nhớ củay
. Nênx
ở ngoài hàm nó không bị ảnh hưởng.
Chính vì đặc điểm sao chép sang ô nhớ mới nên việc chúng ta sửa đổi ở trong hàm nó sẽ không liên quan ghì tới giá trị của biến gốc x
.
🥇 Pass by Reference (Truyền theo tham chiếu)
Đặc điểm: Thay vì sao chép giá trị của biến, thì nó sẽ truyền trực tiếp tham chiếu của biến vào bên trong hàm (tức là tham số của hàm thì nó sẽ nhận luôn tham chiếu của biến bên ngoài)
Giả sử ở ví dụ trên là pass by reference, thì có nghĩa là từ x truyền sang y nó sẽ không có bước sao chép mà thay vào đó cái biến y sẽ tham chiếu cùng biến x
=> Gán lại tham số trong hàm ngay lập tức, biến ngoài hàm cũng bị thay đổi
🥇 Javascript hoàn toàn là pass by value
Dựa vào lý thuyết của pass by value và pass by reference thì có thể khẳng định rằng javascript chỉ là pass by value thôi, nó không hề có pass by reference.
Có thể tới đây các bạn sẽ hơi bối rối tại vì có nhiều tài liệu trên mạng bảo là có pass by reference hoặc có thấy trường hợp truyền object vào bên trong hàm rồi sửa object đấy thì bên ngoài hàm cũng bị sửa theo dẫn đến các bạn lại nghĩ nó là pass by reference. Mình sẽ giải thích cho các bạn rõ từng ý một nhé.
🥈 Chứng minh javascript chỉ có pass by value
Dựa vào đặc điểm của pass by value là gán lại tham số trong hàm, không làm thay đổi biến bên ngoài hàm thì mình sẽ chứng minh cho các bạn thấy.
x vẫn là { name: "Alice" }
bởi vì nó là pass by value, nó là pass by value nên việc chúng ta gán lại tham số ở trong hàm sẽ không làm thay đổi biến ở ngoài hàm
Nếu nó là pass by reference thì khi gán lại tham số trong hàm thì biến ở trong hàm cung bị thay đổi theo.
🥈 Điểm mà javascript bị hiểu nhầm có pass by reference
Thay vì gán lại tham số y, thì người ta gán lại thuộc tính y
Ví dụ
Các bạn lưu ý, như thế này thì nó không phải là pass by reference. Để phản ánh được một ngôn ngữ nó có pass by reference hay không, thì chúng ta phải nhìn vào đặc điểm gán lại tham số ở trong hàm
chứ không phải gán lại thuộc tính của object như ví dụ trên.
Gán lại tham số thì các bạn phải gán y = {name: "Bob"}
, còn y.name = "Bob"
là gán lại thuộc tính.