Var, Const, Let: Cuộc Cách Mạng Biến Số trong JavaScript và Cách Bạn 'Làm Chủ' Chúng!

Var, Const, Let: Cuộc Cách Mạng Biến Số trong JavaScript và Cách Bạn 'Làm Chủ' Chúng!

Chào các bạn, những người đam mê lập trình! Trong thế giới JavaScript năng động, việc quản lý biến số là một kỹ năng cơ bản nhưng cực kỳ quan trọng. Từng có thời, var là "ông hoàng" duy nhất. Nhưng rồi, letconst xuất hiện, mang đến một cuộc cách mạng thực sự. Vậy ba "người anh em" này khác nhau thế nào và khi nào nên dùng ai? Hãy cùng tôi tìm hiểu nhé!

Var: Người Anh Cả "Dễ Dãi" (và đôi khi rắc rối)

  • Phạm vi (Scope): varphạm vi hàm (function scope). Điều này có nghĩa là biến được khai báo với var chỉ có thể truy cập được trong hàm mà nó được định nghĩa, hoặc toàn cục nếu khai báo bên ngoài mọi hàm.
  • Hoisting: Biến khai báo với var được hoisting lên đầu phạm vi của nó. Tức là bạn có thể truy cập biến trước khi nó được khai báo, nhưng giá trị ban đầu sẽ là undefined.
  • Khai báo lại & Gán lại: Bạn có thể khai báo lại và gán lại giá trị cho biến var trong cùng một phạm vi mà không gặp lỗi.
console.log(a); // undefined (hoisted)var a = 10;console.log(a); // 10function exampleVar() {  var x = 5;  if (true) {    var x = 10; // Khai báo lại, không phải biến mới    console.log(x); // 10  }  console.log(x); // 10 (x vẫn là 10 do function scope)}exampleVar();var b = 1;var b = 2; // Khai báo lại hợp lệconsole.log(b); // 2

Vấn đề của var: Do phạm vi hàm và khả năng khai báo lại, var dễ gây ra lỗi khó debug, đặc biệt trong các vòng lặp hoặc khối lệnh if/else.

Let: Kỷ Nguyên Mới của Phạm Vi Khối (Block Scope)

  • Phạm vi (Scope): letphạm vi khối (block scope). Tức là biến chỉ tồn tại trong khối lệnh ({}) mà nó được định nghĩa, bao gồm cả vòng lặp và điều kiện.
  • Hoisting: let cũng được hoisting, nhưng không được khởi tạo. Nếu bạn cố gắng truy cập biến let trước khi khai báo, bạn sẽ gặp lỗi ReferenceError. Vùng này gọi là "Temporal Dead Zone" (TDZ).
  • Khai báo lại & Gán lại: Không thể khai báo lại biến let trong cùng một phạm vi. Tuy nhiên, bạn có thể gán lại giá trị mới cho nó.
// console.log(y); // ReferenceError: Cannot access 'y' before initialization (TDZ)let y = 20;console.log(y); // 20function exampleLet() {  let z = 5;  if (true) {    let z = 10; // Biến z mới, chỉ tồn tại trong khối if    console.log(z); // 10  }  console.log(z); // 5 (biến z bên ngoài khối if)}exampleLet();let c = 1;// let c = 2; // SyntaxError: Identifier 'c' has already been declaredc = 2; // Gán lại hợp lệconsole.log(c); // 2

Const: Biến Hằng Số "Bất Biến" (hay gần như vậy)

  • Phạm vi (Scope): Giống như let, const cũng có phạm vi khối (block scope).
  • Hoisting: Giống như let, const cũng được hoisting nhưng nằm trong Temporal Dead Zone. Phải khai báo và gán giá trị ngay lập tức.
  • Khai báo lại & Gán lại: Không thể khai báo lại và cũng không thể gán lại giá trị cho biến const sau khi đã khởi tạo.
const PI = 3.14;// PI = 3.14159; // TypeError: Assignment to constant variable.const USER = { name: "Alice", age: 30 };USER.age = 31; // Hợp lệ! Có thể thay đổi thuộc tính của đối tượngconsole.log(USER); // { name: "Alice", age: 31 }// USER = { name: "Bob" }; // TypeError: Assignment to constant variable.

Lưu ý quan trọng với const: Khi bạn khai báo một đối tượng hoặc mảng với const, bạn không thể gán lại toàn bộ đối tượng/mảng đó. Tuy nhiên, bạn vẫn có thể thay đổi các thuộc tính bên trong đối tượng hoặc các phần tử của mảng. const đảm bảo rằng tham chiếu đến đối tượng/mảng đó là bất biến, chứ không phải bản thân giá trị bên trong.

Khi nào dùng Var, Let, Const? Thực hành tốt nhất!

Trong lập trình JavaScript hiện đại, hầu hết các developer đều tuân thủ nguyên tắc sau:

  • Luôn ưu tiên const: Nếu biến của bạn không cần thay đổi giá trị sau khi được khởi tạo, hãy dùng const. Điều này giúp code dễ đọc, dễ bảo trì và tránh được nhiều lỗi tiềm ẩn.
  • Dùng let khi cần gán lại: Nếu bạn biết rằng giá trị của biến sẽ thay đổi trong quá trình thực thi (ví dụ: biến đếm trong vòng lặp, biến lưu trữ kết quả có thể được cập nhật), hãy dùng let.
  • Tránh dùng var: Trong hầu hết các trường hợp, bạn nên tránh sử dụng var để hạn chế các vấn đề về phạm vi và hoisting không mong muốn.

Bảng tóm tắt nhanh:

Đặc điểmvarletconst
Phạm vi (Scope)Function scopeBlock scopeBlock scope
HoistingCó, với giá trị undefinedCó, nhưng trong TDZCó, nhưng trong TDZ
Khai báo lạiKhôngKhông
Gán lạiKhông (trừ thuộc tính của object/array)

Việc hiểu rõ và sử dụng đúng var, let, và const không chỉ giúp code của bạn hoạt động chính xác hơn mà còn thể hiện sự chuyên nghiệp và tư duy lập trình hiện đại. Hãy áp dụng ngay những kiến thức này vào dự án của mình để tạo ra những dòng code sạch, mạnh mẽ và dễ bảo trì hơn nhé. Chúc các bạn code vui vẻ!