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

Khác biệt giữa Khai báo (Declare) và Khởi tạo (Initialize) biến trong JavaScript

Theo đặc tả ECMAScript, khai báo (declaration) và khởi tạo (initialization) là 2 bước riêng biệt trong vòng đời biến var.

Quy trình theo Spec

  1. Tạo biến (Creation): Khi Lexical Environment được khởi tạo (vào scope), biến var được tạo ra và gán giá trị undefined.
  2. Khởi tạo (Initialization): Khi dòng code var x = value; được thực thi (runtime), giá trị value được gán cho biến.

Minh họa


console.log(x); // undefined (không lỗi)
var x = 10;
console.log(x); // 10

// Engine hiểu như sau:
// 1. Creation phase (hoisting): var x = undefined;
// 2. Execution phase:
//    console.log(x); // undefined
//    x = 10;         // Initialization (gán giá trị)
//    console.log(x); // 10

Khác biệt chính

Đặc điểmKhai báo (Declaration)Khởi tạo (Initialization)
Thời điểmCompile phase (tạo Lexical Env)Runtime (khi dòng code chạy)
Hành độngĐăng ký biến trong scope, gán undefinedGán giá trị thực từ biểu thức
Ví dụvar x;x = 10 (phần sau =)
Có thể tách biệt?Có (hoisting tách khai báo khỏi gán)Phải cùng dòng với khai báo hoặc sau

let/const khác biệt

  • Cũng bị hoisting (tạo binding trong scope) nhưng ở TDZ (Temporal Dead Zone).
  • Truy cập trước dòng khai báo → ReferenceError.
  • let x; → tạo binding, chưa khởi tạo (uninitialized). let x = 10; → khởi tạo.
  • const x = 10; → bắt buộc khởi tạo ngay khi khai báo.

Function Declaration vs Expression


// Function Declaration: Hoisted hoàn toàn (tạo + khởi tạo function object)
foo(); // OK
function foo() { console.log("Hi"); }

// Function Expression (var): Chỉ khai báo var được hoisted
bar(); // TypeError: bar is not a function
var bar = function() { console.log("Hi"); };

Tại sao quan trọng?

  • Hiểu undefined vs ReferenceError.
  • Tránh bug dùng biến trước khi gán giá trị (logic sai dù không lỗi).
  • Giải thích tại sao function declaration gọi trước định nghĩa được.
  • Cơ sở của let/const TDZ – thiết kế an toàn hơn.

Best Practice

  • Dùng const mặc định – buộc khởi tạo ngay, không gán lại.
  • Dùng let khi cần gán lại – khai báo ở đầu block.
  • Tránh var – hoisting gây nhầm lẫn.
  • Khởi tạo biến ngay khi khai báo: const x = compute() thay vì tách 2 dòng.