JavaScript const, let, var: Khi nào nên dùng?

  • Home
  • JavaScript const, let, var: Khi nào nên dùng?

Khi mới học JavaScript, var, letconst có thể khiến bạn bối rối vì cả ba đều được dùng để khai báo biến. Tuy nhiên, chúng có những khác biệt quan trọng về scope, khả năng gán lại giá trị và hoisting.

Trong JavaScript hiện đại, lựa chọn mặc định nên là const, sau đó dùng let khi biến cần thay đổi giá trị. var chủ yếu nên xuất hiện khi bạn đang làm việc với code JavaScript cũ.


1. var, letconst khác nhau như thế nào?

Ví dụ đơn giản:

var name = "John";

let age = 30;

const country = "Vietnam";

Cả ba đều tạo biến, nhưng hành vi của chúng khác nhau.

Đặc điểm var let const
Có thể gán lại
Block scope
Function scope
Hoisting
Temporal Dead Zone
Khai báo lại cùng scope
Khuyến nghị dùng trong code mới

Điểm quan trọng nhất cần nhớ:

const → mặc định
let   → khi cần thay đổi giá trị
var   → chủ yếu cho code cũ

2. const – lựa chọn mặc định

Trong JavaScript hiện đại, hãy ưu tiên const nếu biến không cần được gán lại.

const username = "John";
const age = 30;
const website = "example.com";

Bạn không thể gán giá trị mới cho biến const:

const age = 30;

age = 31;
// TypeError

Điều này giúp code dễ đọc hơn vì khi nhìn thấy const, bạn biết rằng biến đó không được gán sang một giá trị khác.

Ví dụ:

const apiUrl = "/api/users";
const maxRetry = 3;
const timeout = 5000;

Các giá trị cấu hình như vậy rất phù hợp với const.


3. let – dùng khi giá trị sẽ thay đổi

Nếu biến cần được gán lại trong quá trình chương trình chạy, hãy dùng let.

Ví dụ:

let count = 0;

count++;
count++;
count++;

console.log(count);
// 3

Hoặc:

let status = "loading";

status = "success";

Một ví dụ thực tế hơn:

let total = 0;

for (let i = 0; i < 10; i++) {
    total += i;
}

console.log(total);

Ở đây totali đều thay đổi giá trị nên let là lựa chọn phù hợp.


4. var – cách khai báo biến của JavaScript cũ

Trước ES6, JavaScript chủ yếu sử dụng var.

Ví dụ:

var name = "John";

name = "David";

Code vẫn chạy bình thường.

Tuy nhiên, var có một số đặc điểm dễ gây lỗi, đặc biệt là function scope thay vì block scope.

Đây là lý do var không còn được khuyến khích trong code JavaScript hiện đại.


5. Sự khác biệt quan trọng: Block Scope

Đây là một trong những lý do lớn nhất để ưu tiên letconst.

Xét ví dụ:

if (true) {
    var name = "John";
}

console.log(name);

Kết quả:

John

var không bị giới hạn bởi block {}.

Trong khi đó:

if (true) {
    let name = "John";
}

console.log(name);

Code trên sẽ gây lỗi vì name chỉ tồn tại bên trong block if.

Tương tự với const:

if (true) {
    const name = "John";
}

console.log(name);
// ReferenceError

Đây gọi là block scope.


6. Vì sao Block Scope quan trọng?

Hãy xem một ví dụ thực tế:

let message = "Hello";

if (true) {
    let message = "Welcome";
    console.log(message);
}

console.log(message);

Kết quả:

Welcome
Hello

Hai biến message tồn tại ở hai scope khác nhau.

Điều này giúp tránh việc một đoạn code vô tình thay đổi biến được sử dụng ở nơi khác.


7. const không có nghĩa Object không thể thay đổi

Đây là một hiểu lầm rất phổ biến.

Bạn không thể làm:

const user = {
    name: "John"
};

user = {
    name: "David"
};

Điều này gây lỗi.

Nhưng bạn hoàn toàn có thể thay đổi property của object:

const user = {
    name: "John",
    age: 30
};

user.name = "David";
user.age = 31;

console.log(user);

Kết quả:

{
    name: "David",
    age: 31
}

Tại sao?

Bởi vì const ngăn việc gán lại biến, chứ không làm object trở thành immutable.


8. Array cũng tương tự

Bạn có thể khai báo:

const users = [];

Sau đó thêm phần tử:

users.push("John");
users.push("David");

console.log(users);

Kết quả:

["John", "David"]

Nhưng không thể gán một Array mới:

users = ["Peter"];
// TypeError

Vì vậy:

const users = [];

không có nghĩa là Array không thể thay đổi.

Nó chỉ có nghĩa là biến users không thể trỏ sang một Array khác.


9. var có vấn đề với vòng lặp

Một ví dụ kinh điển:

for (var i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);
    }, 100);
}

Kết quả:

3
3
3

Nguyên nhân là var có function scope và cả ba callback đều sử dụng cùng một biến i.

Nếu sử dụng let:

for (let i = 0; i < 3; i++) {
    setTimeout(() => {
        console.log(i);
    }, 100);
}

Kết quả:

0
1
2

Đây là một trong những ví dụ điển hình cho thấy let an toàn hơn var khi làm việc với loop và callback.


10. Hoisting: var, let, const khác nhau

JavaScript có cơ chế hoisting, tức là các khai báo được xử lý trước khi code thực sự chạy.

Với var:

console.log(name);

var name = "John";

Kết quả:

undefined

Có thể hình dung JavaScript xử lý gần giống:

var name;

console.log(name);

name = "John";

11. letconst cũng được hoist nhưng có Temporal Dead Zone

Ví dụ:

console.log(name);

let name = "John";

Code này gây:

ReferenceError

Tương tự:

console.log(name);

const name = "John";

cũng gây lỗi.

Khoảng thời gian từ lúc scope bắt đầu cho tới khi biến được khai báo được gọi là Temporal Dead Zone (TDZ).

Đây thực tế là một điều tốt vì nó giúp phát hiện lỗi sớm hơn.


12. letconst không thể khai báo lại trong cùng scope

Ví dụ:

let name = "John";

let name = "David";

Sẽ gây lỗi.

Với const cũng vậy:

const age = 30;

const age = 31;

Không hợp lệ.

Trong khi var cho phép:

var name = "John";
var name = "David";

console.log(name);

Kết quả:

David

Đây là một trong những hành vi của var có thể khiến code lớn trở nên khó kiểm soát.


13. Một lỗi thường gặp khi sử dụng const

Bạn không thể khai báo const mà không gán giá trị:

const username;

Code trên không hợp lệ.

Phải viết:

const username = "John";

Trong khi let có thể:

let username;

username = "John";

Do đó, nếu bạn cần khai báo biến trước rồi mới gán giá trị sau, let phù hợp hơn.


14. Quy tắc đơn giản để chọn const, let, var

Bạn có thể sử dụng quy tắc rất đơn giản:

Bước 1: Dùng const trước

const name = "John";
const age = 30;
const users = [];

Bước 2: Nếu cần gán lại → dùng let

let count = 0;

count++;

Bước 3: Không dùng var trong code mới

// Không nên
var name = "John";

// Nên
const name = "John";

15. Ví dụ thực tế

Giả sử bạn xây dựng chức năng lấy danh sách sản phẩm:

const apiUrl = "/api/products";

let products = [];

async function loadProducts() {
    const response = await fetch(apiUrl);

    products = await response.json();

    console.log(products);
}

Ở đây:

const apiUrl

không thay đổi nên dùng const.

let products

có thể được gán dữ liệu mới sau khi API trả về nên dùng let.

Function:

async function loadProducts()

không liên quan trực tiếp đến việc lựa chọn let hay const.


16. Một ví dụ khác với DOM

const button = document.querySelector("#submit");
const message = document.querySelector("#message");

let clickCount = 0;

button.addEventListener("click", () => {
    clickCount++;

    message.textContent = `Clicked ${clickCount} times`;
});

Ở đây:

  • buttonconst
  • messageconst
  • clickCountlet

Đây là cách viết rất phổ biến trong JavaScript hiện đại.


17. Có nên dùng const cho mọi thứ?

Không.

Một số lập trình viên mới học có xu hướng cố gắng dùng const ở mọi nơi.

Ví dụ:

const count = 0;

count++;

Code này sẽ lỗi.

Nếu giá trị chắc chắn thay đổi:

let count = 0;

count++;

là lựa chọn đúng.

Nguyên tắc không phải là:

“Luôn dùng const.”

Mà là:

Dùng const khi không cần gán lại, dùng let khi cần gán lại.


18. Vậy khi nào vẫn cần var?

Trong dự án JavaScript mới, bạn gần như không cần var.

Tuy nhiên, var vẫn có thể xuất hiện khi:

  • Bạn bảo trì dự án JavaScript cũ.
  • Làm việc với code được viết trước ES6.
  • Đang nghiên cứu hoặc hiểu một codebase legacy.
  • Một thư viện hoặc đoạn code cũ yêu cầu cách khai báo này.

Nếu bắt đầu một dự án mới:

const
let

gần như là đủ.


19. Best Practice hiện nay

Một style JavaScript phổ biến là:

const API_URL = "/api/users";

const button = document.querySelector("#load");

let loading = false;

button.addEventListener("click", async () => {
    loading = true;

    const response = await fetch(API_URL);
    const users = await response.json();

    loading = false;

    console.log(users);
});

Bạn có thể thấy một pattern rất rõ:

Không thay đổi → const
Có thay đổi    → let
Code legacy    → var

Kết luận

var, letconst đều là cách khai báo biến trong JavaScript, nhưng trong JavaScript hiện đại, bạn nên ưu tiên constlet.

Quy tắc đơn giản nhất cần nhớ:

const value = 10;

Dùng const khi biến không được gán lại.

let count = 0;

count++;

Dùng let khi biến cần thay đổi giá trị.

var value = 10;

Hạn chế var trong code mới và chủ yếu gặp nó khi làm việc với legacy JavaScript.

Nếu chưa chắc nên chọn gì, hãy bắt đầu bằng:

const

và chỉ chuyển sang:

let

khi bạn thực sự cần gán lại giá trị.

Đó là cách đơn giản nhất để viết JavaScript hiện đại, dễ đọc và ít lỗi hơn.

Categories:

Leave Comment