Ngôn ngữ tương tác cho Web
Hiểu về phạm vi biến và cơ chế hoisting trong JavaScript
Biến khai báo ngoài function/block, truy cập được từ mọi nơi
var global = "everywhere"; // có thể dùng ở mọi nơiBiến khai báo trong function, chỉ truy cập được trong function đó
function test() { var local = "only here"; }let/const trong {...} chỉ truy cập được trong block đó
if (true) { let block = "in block only"; }Scope được xác định bởi vị trí khai báo trong code
function outer() { function inner() { /* có thể dùng biến outer */ } }JavaScript tìm biến từ scope hiện tại lên scope cha
local scope → function scope → global scope| Khai báo | Hoisted | Khởi tạo | TDZ | Ví dụ |
|---|---|---|---|---|
| var | Có | undefined | Không | console.log(x); var x = 5; // undefined, không lỗi |
| let | Có | Không khởi tạo | Có | console.log(x); let x = 5; // ReferenceError |
| const | Có | Không khởi tạo | Có | console.log(x); const x = 5; // ReferenceError |
| function | Có | Toàn bộ function | Không | func(); function func() {} // Hoạt động bình thường |
| function expression | Theo biến chứa | undefined (var) hoặc TDZ (let/const) | Phụ thuộc biến chứa | func(); var func = function() {}; // TypeError |
Dùng let thay vì var hoặc tạo IIFE
// Sai
for (var i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // In ra 3, 3, 3
}
// Đúng
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100); // In ra 0, 1, 2
}Khai báo biến trước khi sử dụng
// Sai console.log(x); // ReferenceError let x = 5; // Đúng let x = 5; console.log(x); // 5
Hiểu rõ scope của từng loại khai báo
// Chú ý
if (true) {
var x = 1; // function scoped
let y = 2; // block scoped
}
console.log(x); // 1 (OK)
console.log(y); // ReferenceErrorNhớ closure "đóng gói" scope của function cha
function outer() {
let count = 0;
return function() { return ++count; };
}
const counter = outer();
// count vẫn tồn tại trong closureSử dụng modules, IIFE hoặc namespaces
// Sai
var data = "global";
// Đúng
(function() {
var data = "encapsulated";
})();Luôn khai báo biến ở đầu scope để tránh confusion về hoisting
// Tốt
function example() {
var x, y, z;
// logic code...
x = 1;
y = 2;
z = x + y;
}Sử dụng let/const để có block scope rõ ràng và tránh hoisting issues
// Tốt const PI = 3.14159; let radius = 5; let area = PI * radius * radius;
Strict mode giúp phát hiện lỗi scope sớm hơn
'use strict'; // Sẽ báo lỗi nếu dùng biến chưa khai báo
Sử dụng IIFE để tạo scope riêng biệt và tránh global pollution
(function() {
// Code trong scope riêng
var private = "not global";
})();Closure giữ lại toàn bộ scope, có thể gây memory leak nếu không cẩn thận
// Cẩn thận với closures trong loops
for (let i = 0; i < 1000; i++) {
// Tạo closure cẩn thận
}