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

Variable Hoisting (Nâng biến) trong JavaScript


Khi bạn có thể sử dụng biến JavaScript trước khi khai báo, đó là do cơ chế hoisting (nâng biến). Parser đọc qua toàn bộ function trước khi thực thi.

Hành vi biến dường như được dùng trước khi khai báo gọi là hoisting:

Ví dụ

points = 200;
var points;

Code trên hoạt động giống hệt:

var points;
points = 200;

Giải thích kỹ thuật

JavaScript engine (V8, SpiderMonkey...) trong Creation Phase của Execution Context sẽ:

  1. Quét toàn bộ scope (global/function) tìm các khai báo var, function.
  2. Tạo binding trong Variable Environment: var → undefined, function → reference đến function object.
  3. Sau đó mới chạy code line-by-line (Execution Phase).

Hoisting với var vs let/const (ES6)

KeywordHoisted?Giá trị khởi tạoTemporal Dead Zone (TDZ)
varCóundefinedKhông
letCóUninitializedCó (ReferenceError nếu truy cập trước khai báo)
constCóUninitializedCó
functionCó (toàn bộ function)Function objectKhông
classCóUninitializedCó

Ví dụ TDZ (Temporal Dead Zone)

console.log(a); // undefined (var hoisted)
console.log(b); // ReferenceError: Cannot access 'b' before initialization (let TDZ)
console.log(c); // ReferenceError (const TDZ)

var a = 1;
let b = 2;
const c = 3;

Function Hoisting

Function Declaration được hoisting toàn bộ (name + body):

sayHello(); // ✅ Hoạt động

function sayHello() {
  console.log("Hello!");
}

Function Expression (gán function cho biến) chỉ hoisting biến (var/let/const), không hoisting function body:

sayHi(); // ❌ TypeError: sayHi is not a function (var) hoặc ReferenceError (let/const)

var sayHi = function() {
  console.log("Hi!");
};

Best Practice

  • Luôn khai báo biến (const ưu tiên, let nếu reassign) trước khi dùng.
  • Dùng const/let thay var (block-scoped, TDZ giúp bắt bug sớm).
  • Function declaration an toàn để gọi trước khi define, nhưng code style hiện đại khuyến khích định nghĩa trước khi dùng.
  • Eslint rule no-use-before-define giúp catch lỗi hoisting.