Có. Từ ES6 (2015), JavaScript hỗ trợ hằng số qua từ khóa const. Trước đó, lập trình viên dùng quy ước UPPER_SNAKE_CASE cho biến var để biểu thị "hằng số" nhưng không có enforcement.
const – Constant Declaration (ES6)
- Tạo read-only binding (liên kết chỉ đọc) – không thể gán lại biến.
- Block scope – giới hạn trong
{ }. - TDZ (Temporal Dead Zone) – không truy cập trước khai báo.
- Bắt buộc khởi tạo ngay –
const x;→ SyntaxError. - Không re-declare trong cùng scope.
Cú pháp
const PI = 3.14159265359;
const API_URL = "https://api.example.com";
const MAX_RETRY = 3;
const DEFAULT_CONFIG = { timeout: 5000, retries: 3 };
const COLORS = ["red", "green", "blue"];
Lưu ý quan trọng: const ≠ Immutable (Bất biến)
const bảo vệ binding (biến không trỏ sang object khác), KHÔNG bảo vệ nội dung object/array.
// Object
const user = { name: "An" };
user.name = "Binh"; // ✅ OK - sửa property
user.age = 25; // ✅ OK - thêm property
// user = {}; // ❌ TypeError - gán lại biến
// Array
const items = [1, 2];
items.push(3); // ✅ OK - sửa mảng
items[0] = 10; // ✅ OK
// items = []; // ❌ TypeError
// Primitive (immutable bản chất)
const x = 10;
// x = 20; // ❌ TypeError
Làm Object/Array thực sự Immutable
// Shallow freeze
const config = Object.freeze({
apiUrl: "/api",
timeout: 5000
});
// config.timeout = 10000; // ❌ TypeError (strict) / fail silently
// Deep freeze (đệ quy)
function deepFreeze(obj) {
Object.freeze(obj);
Object.keys(obj).forEach(key => {
if (typeof obj[key] === "object" && obj[key] !== null) {
deepFreeze(obj[key]);
}
});
return obj;
}
const deepConfig = deepFreeze({
db: { host: "localhost", port: 5432 },
cache: { enabled: true }
});
// deepConfig.db.host = "other"; // ❌ TypeError
Ví dụ từ bài gốc
// Khai báo hằng số
const MY_CONSTANT = "some-value";
// Ví dụ chi tiết
const a = 150;
// ❌ Các thao tác SAI:
a = 0; // TypeError: Assignment to constant variable
a++; // TypeError
var a = 0; // SyntaxError: Identifier 'a' has already been declared
Const trong vòng lặp
// for...of / for...in – const OK (tạo binding mới mỗi iteration)
for (const item of items) { console.log(item); }
for (const key in obj) { console.log(key); }
// for loop truyền thống – PHẢI dùng let (cần gán lại i)
for (let i = 0; i < 10; i++) { ... }
// const i = 0; i++ ❌ TypeError
Best Practice
- Mặc định dùng
constcho mọi khai báo. - Chỉ dùng
letkhi cần gán lại (counter, accumulator, swap). - Đặt tên hằng số toàn cục:
UPPER_SNAKE_CASE. - Dùng
Object.freeze()cho config object literal. - Kết hợp destructuring:
const { a, b } = obj;.
So sánh var / let / const
| Đặc điểm | var | let | const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Hoisting | Có (init undefined) | Có (TDZ) | Có (TDZ) |
| Re-assign | ✅ | ✅ | ❌ |
| Re-declare | ✅ | ❌ | ❌ |
| Init required | Không | Không | ✅ Bắt buộc |
| Temporal Dead Zone | Không | Có | Có |