Trong bài viết này, mình sẽ giải thích cách hoạt động của Pass by value trong JavaScript và cung cấp cho bạn một số ví dụ về việc truyền các biến nguyên thủy và tham chiếu vào một hàm.
JavaScript sử dụng pass by value hay pass by reference?
Trong JavaScript, tất cả các đối số của hàm luôn được truyền bằng giá trị (pass by value). Nó có nghĩa là JavaScript sao chép các giá trị của các biến truyền vào các đối số bên trong hàm.
Bất kỳ thay đổi nào bạn thực hiện đối với các đối số bên trong hàm đều không ảnh hưởng đến các biến truyền bên ngoài hàm.
Nói cách khác, những thay đổi được thực hiện đối với các đối số không được phản ánh bên ngoài hàm.
Nếu các đối số của hàm được truyền bằng tham chiếu (pass by reference), thì những thay đổi của các biến mà bạn chuyển vào hàm sẽ được phản ánh bên ngoài hàm (Điều này không thể thực hiện được trong JavaScript)
#1: Pass by value với các giá trị nguyên thủy trong JS
Đầu tiên, hãy xem ví dụ này:
// Tạo hàm tính bình phương
function square(x) {
x = x * x;
return x;
}
var y = 10;
var result = square(y);
console.log(y); // 10
console.log(result); // 100
Đầu tiên, chúng ta định nghĩa một hàm square()
chấp nhận một đối số x
.
Hàm này sau đó trả về giá trị x
sau khi đã bình phương nó.
Tiếp theo, khai báo biến y
và khởi tạo giá trị của nó thành 10
:
var y = 10;
Sau đó, truyền biến y
vào hàm square()
.
var result = square(y);
Khi truyền biến y
vào hàm square()
, JavaScript sẽ sao chép giá trị của y
vào biến x
.
Sau đó, hàm square()
bình phương x
.
Tuy nhiên, nó không ảnh hưởng đến giá trị của biến y
. Điều này là do x
và y
là các biến hoàn toàn khác nhau. Chúng không liên kết ngược.
Cuối cùng, giá trị của biến y
không thay đổi sau khi hàm square()
được gọi. Bởi vì quá trình này chỉ truyền giá trị của y
(pass by value)
Nếu JavaScript sử dụng pass by reference, giá trị của biến y
sẽ thay đổi thành 100
.
#2: Pass by value với Object trong JS
Rõ ràng là các biến nguyên thủy được truyên theo cách pass by value. Tuy nhiên, đối với các đối tượng (object) thì lại khác.
Ví dụ:
function turnOn(objectX) {
objectX.isOn = true;
}
var lamp = {
isOn: false
};
// Bật đèn lên
turnOn(lamp);
// Kiểm tra xem đèn có đang sáng không?
console.log(lamp.isOn); // true;
Chương trình này hoạt động thế nào?
Đầu tiên, chúng ta định nghĩa một hàm turnOn()
nhận một đối tượng X (objectX
) làm đối số.
function turnOn(objectX) {
objectX.isOn = true;
}
Hàm này đặt thuộc tính isOn
của đối tượng X thành true
.
Tiếp theo, khai báo lamp
và gán cho nó một đối tượng có thuộc tính isOn
được đặt thành false
.
var lamp = {
isOn: false
};
Về cơ bản, lamp
là một biến tham chiếu đến đối tượng thực tế.
Sau đó, chuyển biến lamp
vào hàm turnOn()
.
// Bật đèn lên
turnOn(lamp);
JavaScript lúc này sẽ sao chép giá trị của biến lamp
sang biến objectX
.
Kết quả là, cả biến lamp
và objectX
đều tham chiếu đến cùng một đối tượng trong bộ nhớ:
Sau đó, bên trong hàm turnOn()
, thuộc tính isOn
của đối tượng được đặt thành true
thông qua biến objectX
objectX.isOn = true;
Do đó, bây giờ cả lamp
và objectX
cùng tham chiếu đến một đối tượng có thuộc tính isOn
là true
Do đó, khi bạn log ra consle để xem thuộc tính isOn
của lamp
:
console.log(lamp.isOn);
Thì chúng ta có được kết quả như thế:
Có vẻ như JavaScript truyền một đối tượng theo tham chiếu (pass by value) vì các thay đổi đối với đối tượng được phản ánh bên ngoài hàm.
Tuy nhiên, trường hợp này thì không phải.
Trên thực tế, khi bạn truyền một đối tượng cho một hàm, bạn đang truyền tham chiếu của đối tượng đó, không phải đối tượng thực (máy tính). Do đó, hàm có thể sửa đổi các thuộc tính của đối tượng thông qua tham chiếu của nó.
Ngoài ra, khi bạn truyền một đối tượng vào một hàm, hàm không thể thay đổi biến tham chiếu để tham chiếu đến một đối tượng khác.
Điều này được chứng minh qua ví dụ sau:
function turnOn(objectX) {
objectX = {
isOn: true
};
}
var lamp = {
isOn: false
};
turnOn(lamp);
console.log(lamp.isOn); // false;
Lần này, hàm turnOn()
thay đổi đối số của objectX
để nó tham chiếu đến một đối tượng khác.
Trước khi truyền đối tượng lamp
đến hàm turnOn()
, thuộc tính isOn
của đối tượng lamp
là false
.
Nếu biến lamp
được chuyển bằng tham chiếu (pass by reference), biến lamp
sẽ được thay đổi và tham chiếu đến đối tượng mới có thuộc tính isOn
là true
.
Tuy nhiên, khi chúng ta truy cập thuộc tính isOn
bên ngoài hàm, ta vẫn nhận được false
.
Điều này chỉ ra rằng tham chiếu ban đầu không thay đổi mặc dù đối số đã được thay đổi bên trong hàm.
Tóm lại
JavaScript sử dụng pass by value, truyền mọi đối số cho hàm bằng giá trị.
> Nếu bạn yêu thích JavaScript và muốn đi sâu hơn thì hãy tham gia HỌC FRONT END (Chuyên sâu với HTML, CSS, JavaScript và React) ngay và luôn!
---
HỌC VIỆN ĐÀO TẠO CNTT NIIT - ICT HÀ NỘI
Học Lập trình chất lượng cao (Since 2002). Học thực tế + Tuyển dụng ngay!
Đc: Tầng 3, 25T2, N05, Nguyễn Thị Thập, Cầu Giấy, Hà Nội
SĐT: 02435574074 - 0383.180086
Email: hello@niithanoi.edu.vn
Fanpage: https://facebook.com/NIIT.ICT/
#niit #icthanoi #niithanoi #niiticthanoi #hoclaptrinh #khoahoclaptrinh #hoclaptrinhjava #hoclaptrinhphp