Bài 2 · Cơ bản · 20 phút· Cập nhật 11/06/2026
Biến & kiểu dữ liệu JavaScript
Biên soạn bởi Nguyễn Anh Tuấn
Biến let/const và kiểu dữ liệu JavaScript: number, string, boolean, null vs undefined; == vs === và ép kiểu (type coercion) - kèm bẫy float khi lưu tiền.
Biến là cái tên bạn đặt cho một giá trị. JavaScript hiện đại có hai cách khai báo: let (đổi được) và const (không gán lại). Cả hai đều block-scope - chỉ sống trong cặp { } chứa nó.
let đổi được · const không gán lại
let diem = 8; // doi duoc
diem = 9; // OK
const ten = "Lan"; // khong gan lai
// ten = "Hoa"; // TypeError: Assignment to constant variable
// const KHONG dong bang object - chi chan gan lai bien:
const sv = { ten: "Lan" };
sv.ten = "Hoa"; // OK (van sua duoc thuoc tinh) - ▸Mặc định dùng const; chỉ dùng let khi thật sự cần gán lại.
- ▸let và const đều block-scope - sống trong cặp { } gần nhất.
- ▸const chặn GÁN LẠI biến, không “đóng băng” object (vẫn sửa được thuộc tính).
Vì sao tránh var?
JavaScript có 7 kiểu nguyên thuỷ (primitive): number, string, boolean, null, undefined, bigint, symbol - cộng với object (gồm cả mảng và hàm). Toán tử typeof cho biết kiểu của một giá trị:
typeof - và vài kết quả bất ngờ
typeof 42 // "number"
typeof "hi" // "string"
typeof true // "boolean"
typeof undefined // "undefined"
typeof 10n // "bigint"
typeof Symbol() // "symbol"
typeof null // "object" <- bug lich su!
typeof {} // "object"
typeof [1, 2] // "object" (mang la object - dung Array.isArray)
typeof function(){} // "function" - ▸7 kiểu nguyên thuỷ: number, string, boolean, null, undefined, bigint, symbol.
- ▸Mọi thứ còn lại (mảng, hàm, ngày tháng…) đều là object.
- ▸typeof cho biết kiểu - nhưng có vài “quirk” cần nhớ (xem callout).
Hai quirk của typeof
Khác C hay Python (có int và float riêng), JavaScript chỉ có một kiểu số dùng hằng ngày: number, chính là double IEEE 754 (64-bit). Số nguyên hay số thực đều dùng chung kiểu này (BigInt là kiểu riêng, chỉ dành cho số nguyên cực lớn) - tiện, nhưng kéo theo bẫy số thực gần đúng:
một kiểu number cho tất cả
typeof 7 // "number"
typeof 7.5 // "number" (cung mot kieu!)
0.1 + 0.2 // 0.30000000000000004
0.1 + 0.2 === 0.3 // false
1 / 0 // Infinity
0 / 0 // NaN (Not a Number)
Number.isInteger(7) // true
9007199254740993n // so nguyen RAT lon -> dung BigInt (hau to n) Hệ quả nguy hiểm nhất là khi xử lý tiền. Cộng 0.10 nhiều lần bằng number - nó trông đúng nhưng không đúng:
- ▸JS chỉ có một kiểu number = double IEEE 754; không tách int/float.
- ▸number là số GẦN ĐÚNG: đừng so hai number bằng === sau khi tính toán.
- ▸Có NaN (không phải số) và Infinity; số nguyên cực lớn dùng BigInt (10n).
- ▸TIỀN: lưu bằng số nguyên đơn vị nhỏ nhất (xu) - đừng dùng number/float.
Trung thực về tiền
Chuỗi (string) đặt trong nháy đôi, nháy đơn, hoặc dấu huyền ` (template literal - chèn được biến). boolean chỉ có true/false. Còn hai “giá trị rỗng” hay nhầm lẫn: undefined (chưa gán) và null (cố ý rỗng).
chuỗi, template literal, và rỗng
const ten = "Lan";
const tuoi = 16;
const cau = `Meo con ${ten}, ${tuoi} tuoi`; // template literal
console.log(cau); // Meo con Lan, 16 tuoi
let x; // chua gan -> undefined
let y = null; // co y de rong
Boolean("") // false (chuoi rong la falsy)
Boolean("0") // true (chuoi co ky tu -> truthy!)
Boolean([]) // true (mang rong VAN truthy) - ▸Template literal dùng dấu huyền và chèn biến, viết chuỗi nhiều dòng dễ dàng.
- ▸undefined = chưa gán (JS tự gán); null = cố ý để rỗng (bạn gán).
- ▸Mỗi giá trị có “tính đúng/sai” (truthy/falsy) khi đứng trong if.
Các giá trị falsy
Đây là chỗ JavaScript làm người mới đau đầu nhất. === so sánh cả kiểu lẫn giá trị, không ép kiểu - khác kiểu là false ngay. Còn == ép kiểu (coercion) hai bên về cùng kiểu RỒI mới so, sinh ra hàng loạt kết quả bất ngờ:
ép kiểu lặng lẽ
"5" - 2 // 3 (chuoi -> so)
"5" + 2 // "52" (so -> chuoi; + uu tien NOI chuoi)
1 == "1" // true (ep kieu roi so)
1 === "1" // false (khac kieu -> false ngay)
0 == "" // true
0 === "" // false
null == undefined // true
null === undefined // false
NaN === NaN // false (NaN khong bang ca chinh no!) | Biểu thức | == | === |
|---|---|---|
| 1, "1" | true | false |
| 0, "" | true | false |
| 0, "0" | true | false |
| "", "0" | false | false |
| null, undefined | true | false |
| NaN, NaN | false | false |
- ▸LUÔN dùng === và !== - bỏ qua == để tránh bẫy ép kiểu.
- ▸Cần đổi kiểu thì làm TƯỜNG MINH: Number(x), String(x), Boolean(x).
- ▸NaN không bằng chính nó: kiểm tra bằng Number.isNaN(x).
Tiếp theo
Câu hỏi thường gặp
Mặc định dùng const; chỉ dùng let khi cần gán lại biến. TRÁNH var: nó phạm vi theo hàm (function scope) và bị “hoisting” nên dễ gây bug. Lưu ý: const chặn việc GÁN LẠI biến, chứ KHÔNG “đóng băng” object - bạn vẫn sửa được thuộc tính của object khai báo bằng const.
Vì number của JavaScript là double IEEE 754 - số thực GẦN ĐÚNG. 0.1 và 0.2 không biểu diễn chính xác được trong hệ nhị phân, nên tổng ra 0.30000000000000004. Đừng so hai number bằng == ; và TUYỆT ĐỐI đừng lưu tiền bằng number (xem Bước 3).
Đó là một bug lịch sử từ năm 1995, được giữ lại để không phá vỡ code cũ trên toàn web. Nhớ: typeof null === "object" nhưng null KHÔNG phải object. Mảng cũng cho ra "object" - muốn kiểm tra mảng hãy dùng Array.isArray(x).
undefined = “chưa có giá trị” (JS tự gán khi bạn khai báo mà chưa gán, hoặc hàm không return). null = “cố ý để rỗng” (do lập trình viên gán). typeof undefined là "undefined", còn typeof null là "object". null == undefined là true (do ép kiểu), nhưng null === undefined là false.
Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.
Trả lời vài câu để chắc rằng em đã nắm bài.
Theo bài, mặc định nên khai báo biến bằng cái nào và vì sao tránh var?
- 1
let vs const
Khai báo
const ten = "..."rồi thử gán lạiten = "...". Lỗi gì? Đổi sangletxem sao.Hoàn thành khi:
constgán lại →TypeError: Assignment to constant variable. Đổi sangletthì gán lại được. - 2
typeof
In
typeofcho:42,"hi",true,undefined,null,[1, 2],{}. Cái nào gây bất ngờ?Hoàn thành khi:
nullvà[1,2]đều ra"object"- bug lịch sử củanull, và mảng vốn là object. - 3
Bẫy số thực
In ra
0.1 + 0.2và0.1 + 0.2 === 0.3.Hoàn thành khi:
0.30000000000000004vàfalse-numberlà số gần đúng. - 4
== vs ===
Đoán trước rồi kiểm:
0 == "",0 === "","1" == 1,"1" === 1,null == undefined,null === undefined.Hoàn thành khi:
true, false, true, false, true, false.===khác kiểu làfalsengay. - 5
Tiền
Dùng công cụ ở Bước 3: cộng 0.10 nhiều lần. So float với số nguyên xu.
Hoàn thành khi: Float trôi số (float == số đúng → false); lưu bằng số nguyên xu thì đúng tuyệt đối.
- 6
Truthy / falsy
Liệt kê các giá trị falsy của JS.
"0"và[](mảng rỗng) là truthy hay falsy?Hoàn thành khi: Falsy:
false,0,"",null,undefined,NaN(và0n)."0"và[]đều TRUTHY.