Cảm ơn bạn!
Lexical scope trong JavaScript là gì? Nắm chắc những thứ cơ bản để học Javascript tốt hơn
Ở bài viết trước thì chúng ta đã tìm hiểu về khái niệm scope
trong JavaScript. Trong bài viết lần này, ta sẽ tìm hiểu về lexical scope
hay static scope
và xem nó có gì thú vị nhé 😁.
Lexical scope trong JavaScript là gì?
Trước tiên, mình xin sử dụng lại ví dụ từ bài viết hôm trước. Bạn nào chưa hiểu về scope
có thể đọc bài viết này: Scope trong JavaScript là gì?.
function hamOBenNgoai() {
// scope
let text = 'outside';
function hamOBenTrong() {
// scope
console.log(text); // outside
}
hamOBenTrong();
}
hamOBenNgoai();
Một câu hỏi đặt ra là: "Làm sao JavaScript có thể hiểu được biến text
trong hamOBenTrong()
là biến từ hamOBenNgoai()
?".
JavaScript có một cơ chế xác định scope
có tên là lexical scope
hay static scope
.
Lexical scope là nơi mà một biểu thức được tạo ra.
Lexical scope hiểu đơn giản là một biến được khai báo bên ngoài một hàm, có thể truy xuất được khi sử dụng biến này bên trong một hàm khác. Điều ngược lại là không đúng. Các biến được khai báo bên trong một hàm sẽ không thể sử dụng được bên ngoài hàm đó.
Cùng xem một ví dụ để hiểu hơn về lexical scope
nhé:
const user = 'Hung';
function hamBenNgoai() {
const phone = 123123;
console.log(user); // Hung
function hamBenTrong() {
const old = 22;
console.log(user, phone); // Hung, 123123
function hamBenTrongCung() {
console.log(user, phone, old); // Hung, 123123, 22
}
hamBenTrongCung();
}
hamBenTrong();
}
hamBenNgoai();
Ở ví dụ trên ta khai báo một biến user
ở global scope
. Ta thực thi (invoked) hàm hamBenNgoai()
. Trong hàm này ta sử dụng biến user
từ global scope
👌. Vậy câu hỏi đặt ra là lexical scope của user
thuộc phạm vi toàn cục (global scope
) hay scope của hamBenNgoai()
?
lexical scope có nghĩa là chúng ta đang xét về không gian định nghĩa chứ không phải là nơi mà ta gọi user
. Do đó, lexical scope của user
là global scope
vì ta đã khai báo user
ở global environment ^^.
Cùng tiếp tục theo dõi ví dụ trên, ta thấy lexical scope của hamBenTrongCung()
bao gồm cả scope của hamBenTrong()
, hamBenNgoai()
và global scope. Ta có thế truy cập các biến khi ở trong lexical scope của biến đó. Chính vì thế trong hamBenTrong()
ta có thể sử dụng biến user
, phone
, old
.
lexical scope của hamBenTrong()
bao gồm scope của hamBenNgoai()
và global scope. Do đó ta có thể sử dụng biến user
, phone
, vì ta đang sử dụng các biến này trong lexical scope của chúng.
lexical scope của hamBenNgoai()
là global scope. Nên ta chỉ có thể sử dụng được biến user
ở ví dụ trên 😁.
Tiếp tục một ví dụ nữa để các bạn hiểu rõ hơn nhé ^^. Ví dụ này mình đã lấy từ bài trước:
function sinhVienCNTT() {
let tenSinhVien = 'Trang';
let mssv = 1851120000;
}
function dangKyMonHoc(){
console.log(mssv);
}
sinhVienCNTT();
dangKyMonHoc(); // mssv is not defined
Ở ví dụ trên, ta sẽ gặp một lỗi đó là mssv is not defined
. Như chúng ta đã tìm hiểu về lexical scope đó là ta chỉ có thể sử dụng được biến mssv
khi ta dùng biến đó ở trong lexical scope của nó.
Ta khai báo biến mssv
trong sinhVienCNTT()
do đó lexical scope của mssv
là scope sinhVienCNTT()
. Đối với dangKyMonHoc()
, lexical scope của nó là global scope. Chính vì hai lexical scope này khác nhau nên ta không thể sử dụng biến mssv
trong dangKyMonHoc()
được 😁😊.
Kết luận
Chúng ta đã cùng nhau tìm hiểu về lexical scope trong JavaScript rồi. Hy vọng bài viết sẽ giúp các bạn hiểu về lexical scope hơn ^^.
Chúc các bạn học tốt.