Scope (phạm vi) xác định nơi biến có thể được truy cập. JavaScript (ES5-) có 2 scope chính: Global và Function (Local). ES6+ thêm Block scope cho let/const.
1. Global Scope
Biến khai báo ngoài mọi hàm. Truy cập được mọi nơi trong chương trình.
var globalVar = "Tôi là global";
function show() { console.log(globalVar); } // Truy cập được
Trong trình duyệt, global variable gắn vào window: window.globalVar.
2. Function Scope (Local Scope - ES5)
Biến khai báo bằng var bên trong hàm. Chỉ truy cập được trong hàm đó.
function demo() {
var localVar = "Chỉ trong hàm";
console.log(localVar); // OK
}
demo();
console.log(localVar); // ReferenceError
3. Block Scope (ES6 - let/const)
Biến let/const bị giới hạn trong cặp { } gần nhất (if, for, while, block đơn lẻ).
if (true) {
let blockVar = "Chỉ trong block";
const blockConst = "Cũng chỉ trong block";
var functionScoped = "Ra ngoài hàm được";
}
console.log(blockVar); // ReferenceError
console.log(functionScoped); // OK (var không quan tâm block)
Che giấu biến (Variable Shadowing)
Biến local trùng tên biến global sẽ "che" biến global trong scope local.
var name = "Global";
function greet() {
var name = "Local"; // Che biến global
console.log(name); // "Local"
}
greet();
console.log(name); // "Global"
Ví dụ minh họa scope
var myVar = "global";
function checkScope() {
var myVar = "local"; // Khai báo mới, che biến global
console.log(myVar); // "local"
}
checkScope(); // "local"
console.log(myVar); // "global"
Hoisting & Scope
var: Hoisted lên đầu function scope, khởi tạo =undefined.let/const: Hoisted lên đầu block scope nhưng ở TDZ (Temporal Dead Zone) – truy cập trước khai báo báo lỗi.function declaration: Hoisted hoàn toàn (cả tên lẫn body).
Lexical Scoping (Phạm vi từ vựng)
JS dùng lexical scoping: scope được xác định bởi vị trí viết code (thời gian compile), không phải nơi gọi hàm (runtime).
function outer() {
var x = 10;
function inner() {
console.log(x); // Truy cập x của outer (lexical)
}
return inner;
}
var fn = outer();
fn(); // 10 - inner nhớ x của outer (closure)
Best Practice
- Dùng
constmặc định,letkhi cần gán lại. Tránhvar. - Khai báo biến ở đầu scope (block/hàm) để dễ đọc.
- Hạn chế biến global – dùng module pattern, IIFE, ES Modules.
- Tận dụng block scope của
let/consttrong vòng lặp, if.