Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Có thể sử dụng biến JavaScript trước khi khai báo không? (Hoisting)

Có, bạn có thể. Hiện tượng này gọi là Hoisting (nâng lên) – trình phân tích JavaScript di chuyển việc khai báo biến (không phải gán giá trị) lên đầu phạm vi (scope) trước khi thực thi mã.

Cơ chế Hoisting

Khi engine JavaScript biên dịch code, nó quét toàn bộ hàm/script để tìm các khai báo var, function, let, const, class và "nâng" phần khai báo lên đầu scope. Phần gán giá trị (= value) giữ nguyên vị trí.

Ví dụ với var

console.log(rank); // undefined (không báo lỗi ReferenceError)
var rank = 5;
console.log(rank); // 5

// Engine hiểu như sau:
var rank;           // Khai báo được nâng lên
console.log(rank);  // undefined
rank = 5;           // Gán giá trị giữ nguyên chỗ
console.log(rank);  // 5

Lưu ý quan trọng: let và const cũng bị hoisting nhưng khác

  • Chúng bị nâng lên nhưng ở Temporal Dead Zone (TDZ) từ đầu scope đến dòng khai báo.
  • Truy cập trước khai báo gây ReferenceError.
console.log(x); // ReferenceError: Cannot access 'x' before initialization
let x = 10;

Function Declaration vs Function Expression

// Function Declaration: cả tên và body đều được hoisting
foo(); // "Hello"
function foo() { console.log("Hello"); }

// Function Expression (var): chỉ tên được hoisting
bar(); // TypeError: bar is not a function
var bar = function() { console.log("World"); };

// Function Expression (let/const): TDZ
baz(); // ReferenceError
let baz = function() { console.log("!"); };

Tại sao hiểu Hoisting quan trọng?

  • Tránh bug lạ khi dùng biến trước khi gán giá trị (giá trị sẽ là undefined).
  • Hiểu tại sao function declaration có thể gọi trước khi định nghĩa.
  • Viết code an toàn: luôn khai báo biến ở đầu scope (hoặc dùng let/const).

Khuyến nghị

  • Dùng let và const (ES6+) thay vì var – TDZ giúp phát hiện lỗi sớm.
  • Khai báo biến ở đầu hàm/block.
  • Sử dụng linter (ESLint) với rule no-use-before-define.