Cách hoạt động phạm vi biến (Scope) trong JavaScript
Javascript căn bản | by
Trong JavaScript, phạm vi biến (Scope) đóng vai trò quan trọng trong việc xác định nơi một biến có thể được truy cập và khi nào nó sẽ bị hủy. Việc hiểu rõ phạm vi biến giúp lập trình viên quản lý bộ nhớ hiệu quả, tránh lỗi xung đột biến, và viết code dễ bảo trì hơn.
JavaScript có nhiều loại phạm vi, bao gồm phạm vi toàn cục (Global Scope), phạm vi hàm (Function Scope), phạm vi khối (Block Scope), và còn có các khái niệm nâng cao như Lexical Scope và Closure. Ngoài ra, cơ chế hoisting cũng ảnh hưởng đến cách biến được sử dụng trong từng phạm vi.
Trong bài viết này, mình sẽ cùng tìm hiểu về các loại phạm vi biến trong JavaScript, cách chúng hoạt động, và cách áp dụng phạm vi biến một cách hiệu quả trong lập trình thực tế.
Phạm vi biến (Scope) trong JavaScript
Scope (phạm vi biến) trong JavaScript là vùng mà một biến có thể được truy cập và sử dụng. Nó xác định biến đó có thể được sử dụng ở đâu trong mã nguồn và khi nào nó bị hủy.
JavaScript có nhiều loại phạm vi khác nhau, bao gồm:
- Phạm vi toàn cục (Global Scope) – Biến có thể được truy cập ở mọi nơi trong chương trình.
- Phạm vi hàm (Function Scope) – Biến chỉ có thể được truy cập bên trong hàm nơi nó được khai báo.
- Phạm vi khối (Block Scope) – Biến được khai báo trong một khối
{}
chỉ có thể được truy cập trong khối đó (áp dụng vớilet
vàconst
). - Lexical Scope (Phạm vi từ vựng) – Các hàm con có thể truy cập biến của hàm cha nơi chúng được khai báo.
Ảnh hưởng của phạm vi biến đến việc truy cập và quản lý biến
Phạm vi biến ảnh hưởng đến cách chúng ta có thể truy xuất và thay đổi giá trị của biến:
- Biến toàn cục có thể truy cập từ bất kỳ đâu nhưng dễ bị thay đổi ngoài ý muốn.
- Biến cục bộ trong hàm chỉ tồn tại trong hàm và giúp tránh xung đột với biến toàn cục.
- Biến trong khối (block scope) với
let
vàconst
giúp kiểm soát biến tốt hơn. - Phạm vi từ vựng (Lexical Scope) giúp hàm con truy cập được biến của hàm cha.
Ví dụ minh họa về phạm vi biến
Phạm vi toàn cục (Global Scope)
let globalVar = "Tôi là biến toàn cục"; function showGlobalVar() { console.log(globalVar); // Có thể truy cập biến toàn cục } showGlobalVar(); // Output: Tôi là biến toàn cục console.log(globalVar); // Output: Tôi là biến toàn cục
Phạm vi hàm (Function Scope)
function myFunction() { let localVar = "Tôi là biến cục bộ"; console.log(localVar); // Truy cập được bên trong hàm } myFunction(); console.log(localVar); // Lỗi: localVar không được định nghĩa ngoài hàm
Phạm vi khối (Block Scope) với let và const
{ let blockVar = "Tôi là biến trong khối"; console.log(blockVar); // Truy cập được trong khối } console.log(blockVar); // Lỗi: blockVar không được định nghĩa ngoài khối
Lexical Scope (Phạm vi từ vựng)
function outerFunction() { let outerVar = "Tôi là biến của hàm cha"; function innerFunction() { console.log(outerVar); // Truy cập được biến của hàm cha } innerFunction(); } outerFunction(); // Output: Tôi là biến của hàm cha
Các loại phạm vi biến trong JavaScript
JavaScript có nhiều loại phạm vi biến khác nhau, ảnh hưởng đến cách biến được truy cập và sử dụng. Dưới đây là chi tiết về từng loại phạm vi biến.
Phạm vi toàn cục (Global Scope)
Phạm vi toàn cục là phạm vi rộng nhất trong JavaScript. Một biến được khai báo bên ngoài tất cả các hàm hoặc khối {}
sẽ thuộc phạm vi toàn cục. Biến này có thể được truy cập và thay đổi từ bất kỳ đâu trong chương trình.
Rủi ro khi sử dụng biến toàn cục
- Gây xung đột biến: Nếu nhiều phần của chương trình sử dụng cùng một biến toàn cục, có thể xảy ra ghi đè giá trị không mong muốn.
- Gây khó khăn khi debug: Khi nhiều hàm có thể thay đổi giá trị của biến toàn cục, việc tìm nguyên nhân lỗi trở nên phức tạp.
- Chiếm tài nguyên không cần thiết: Biến toàn cục tồn tại trong toàn bộ vòng đời của chương trình, có thể gây lãng phí bộ nhớ.
let globalVar = "Tôi là biến toàn cục"; function showGlobalVar() { console.log(globalVar); // Truy cập được biến toàn cục } showGlobalVar(); // Output: Tôi là biến toàn cục console.log(globalVar); // Output: Tôi là biến toàn cục
Giải thích: Biến globalVar
được khai báo ngoài hàm, nên có thể truy cập từ bất cứ đâu.
Phạm vi hàm (Function Scope)
Phạm vi hàm là phạm vi của một biến khi nó được khai báo bên trong một hàm bằng var
, let
hoặc const
. Biến có phạm vi hàm chỉ có thể được truy cập bên trong hàm đó.
Đặc điểm quan trọng
- Biến trong phạm vi hàm không thể truy cập từ bên ngoài hàm.
- Khi hàm kết thúc, biến trong hàm sẽ bị xóa khỏi bộ nhớ (trừ khi được lưu trữ trong closure).
function myFunction() { let localVar = "Tôi là biến cục bộ"; console.log(localVar); // Truy cập được bên trong hàm } myFunction(); console.log(localVar); // Lỗi: localVar không được định nghĩa ngoài hàm
Giải thích: localVar
chỉ tồn tại trong myFunction()
, nên khi gọi console.log(localVar)
bên ngoài, JavaScript báo lỗi.
Phạm vi khối (Block Scope – let, const)
Phạm vi khối (Block Scope) chỉ áp dụng với biến khai báo bằng let
và const
. Một biến có phạm vi khối chỉ có thể được truy cập trong cặp {}
nơi nó được khai báo.
So sánh với var
var
không có block scope – Nếu khai báo trong{}
, biến vẫn có thể truy cập bên ngoài.let
vàconst
có block scope – Biến không thể truy cập ngoài{}
.