Vòng đời của biến JavaScript bắt đầu từ khi được khai báo (declared) và kết thúc tùy thuộc vào phạm vi (scope) của nó.
1. Biến cục bộ (Local Variables)
- Khai báo: Bên trong một hàm (function) bằng
var,let,const. - Phạm vi: Chỉ trong hàm đó (Function Scope cho
var, Block Scope cholet/const). - Tham số hàm cũng là biến cục bộ.
- Vòng đời: Tạo khi hàm được gọi -> Hủy khi hàm kết thúc thực thi (return hoặc hết code).
- Mỗi lần gọi hàm -> Tạo bản sao biến cục bộ mới.
2. Biến toàn cục (Global Variables)
- Khai báo: Bên ngoài mọi hàm, hoặc gán giá trị cho biến chưa khai báo (trong non-strict mode - tránh), hoặc gán vào
window/global. - Phạm vi: Toàn bộ chương trình (Global Scope). Truy cập được ở mọi nơi.
- Vòng đời:
- Trình duyệt: Tồn tại cho đến khi đóng tab/trình duyệt hoặc load trang mới (navigation).
- Node.js: Tồn tại suốt vòng đời process.
- Lưu ý: Nếu load trang mới trong cùng tab (không đóng tab), biến global KHÔNG bị xóa (vẫn giữ giá trị) - do bfcache (Back/Forward Cache) hoặc session restore. Khuyến nghị: không phụ thuộc hành vi này.
3. Block Scope (ES6+) - let / const
Biến khai báo bằng let hoặc const trong cặp ngoặc nhọn { } (block: if, for, while, try/catch, hoặc block đơn lẻ):
- Phạm vi: Chỉ trong block
{ }đó. - Vòng đời: Tạo khi vào block -> Hủy khi ra khỏi block.
- Temporal Dead Zone (TDZ): Từ đầu block đến dòng khai báo -> Truy cập bị
ReferenceError.
Ví dụ minh họa
<!DOCTYPE html>
<html>
<body onload="checkScope()">
<script>
// 1. Global variable
var myVar = "global";
function checkScope() {
// 2. Local variable (Function Scope - var)
var myVar = "local (var)";
// 3. Block Scope (let/const)
if (true) {
let blockVar = "block (let)";
const blockConst = "block (const)";
console.log("Trong block:", blockVar, blockConst); // OK
}
// console.log(blockVar); // ReferenceError: blockVar is not defined
console.log("Trong hàm:", myVar); // "local (var)"
}
checkScope();
console.log("Ngoài hàm (global):", myVar); // "global"
</script>
</body>
</html>
Output
Trong block: block (let) block (const)
Trong hàm: local (var)
Ngoài hàm (global): global
So sánh tóm tắt
| Loại biến | Khai báo | Phạm vi | Vòng đời bắt đầu | Vòng đời kết thúc |
|---|---|---|---|---|
| Global (var/let/const ở top-level) | Ngoài function | Toàn chương trình (window/global) | Load script | Đóng tab / Process exit |
| Function Local (var) | Trong function | Function Scope | Gọi hàm | Hàm return / kết thúc |
| Block Local (let/const) | Trong { } | Block Scope | Vào block (TDZ trước khai báo) | Ra khỏi block |
| Function Parameter | Trong ( ) hàm | Function Scope | Gọi hàm | Hàm kết thúc |
Best Practices
- Tránh biến toàn cục: Dùng IIFE, Module (ESM), Namespace object.
- Luôn dùng
let/const(ES6+) thayvar-> Block scope an toàn, tránh hoisting bug. - Hạn chế scope: Khai báo biến ở scope hẹp nhất có thể (block > function > global).
- Cleanup: Gán
nullcho object lớn không dùng nữa trong scope dài (global, closure) để GC giải phóng bộ nhớ.
Kết luận: Biến cục bộ (local) sống trong một lần gọi hàm. Biến block (let/const) sống trong block { }. Biến toàn cục (global) sống suốt phiên làm việc trình duyệt/process. Hiểu vòng đời giúp quản lý bộ nhớ, tránh rò rỉ biến, bug khó tìm.