Câu 1typeof null trả về gì?
Tổng Kết Kiểu Dữ Liệu — typeof và Bảng Tra Cứu Nhanh
Sắp xếp lại các kiểu đã học: 7 kiểu nguyên thủy và Object, typeof trả về gì, và cách nhận ra mảng.
Giá trị JavaScript trải rộng từ chuỗi, số, boolean, mảng, object, null, undefined, Map, và Set. Trong công việc thực tế, bạn kiểm tra một giá trị đến từ một form hay một server có đúng kiểu bạn mong đợi trước khi xử lý nó.
Bài này sắp xếp lại tất cả từ một góc độ duy nhất — kiểu — tóm tắt typeof trả về gì và cách kiểm tra đúng cho mỗi kiểu.
Kiểu Chia Thành 7 Giá Trị Nguyên Thủy và Object
Biết kiểu của một giá trị quyết định bạn có thể làm gì với nó. Một chuỗi cho bạn length và slice; một số cho phép bạn tính toán; một mảng cho bạn push.
Hiểu sai kiểu trong lúc xử lý một giá trị vừa nhận, mặt khác, và undefined hay NaN có thể trượt hết đến cuối mà bạn không nhận ra.
Giá trị của JavaScript chia thành giá trị nguyên thủy (primitives) (7 loại: number, string, boolean, null, undefined, symbol, và bigint — các giá trị không phải object hay mảng) và Object (giá trị giữ property; mảng, Map, và Set đều thuộc nhóm này).
Khóa học này đã nói về 5 giá trị nguyên thủy đầu và Object.
Trong 2 cái còn lại, symbol (giá trị để tạo một key duy nhất không bao giờ trùng) được dùng khi bạn cần một loại key đặc biệt, và bigint (giá trị chuyên dùng để xử lý số nguyên cực lớn) được dùng cho số nguyên quá lớn để Number biểu diễn chính xác. Không cái nào xuất hiện trong phạm vi khóa học này, nên biết tên và vị trí của chúng là đủ.
Toán tử kiểm tra kiểu là typeof. Viết nó trước một giá trị, và nó trả về tên kiểu dưới dạng chuỗi.
Cái nó trả về cố định thành 8 loại: "string" "number" "boolean" "undefined" "symbol" "bigint" "object" "function". "function" chỉ trả về khi bạn truyền một hàm — hàm sẽ nói ở nhóm tiếp theo.
| Giá Trị Ví Dụ | Nhóm | Kết Quả typeof |
|---|---|---|
| Một chuỗi như ORD-6033 | Nguyên thủy | string |
| Một số như 9800 | Nguyên thủy | number |
| true và false | Nguyên thủy | boolean |
| Một biến chưa gán giá trị | Nguyên thủy | undefined |
| null | Nguyên thủy | object |
| Object và mảng | Object | object |
console.log(typeof "ORD-6033"); // string
console.log(typeof 9800); // number
console.log(typeof true); // boolean
console.log(typeof undefined); // undefined
console.log(typeof { orderId: "ORD-6033" }); // object
console.log(typeof [1, 2]); // object
// null cũng là giá trị nguyên thủy, nhưng typeof trả về object
console.log(typeof null); // object
3 Thứ typeof Trả Về object — null, Mảng, và Object
Một giá trị đến từ một server là một "object địa chỉ vận chuyển," một "null chưa chọn," hay một "mảng sản phẩm" thay đổi việc bạn làm gì tiếp theo với nó. Nhưng typeof trả về cùng "object" cho cả 3, nên nó không dùng được trực tiếp cho kiểm tra này.
typeof null trả về "object" là hành vi của JavaScript từ những ngày đầu tiên. Đó là một lỗi đặc tả đã biết, nhưng sửa nó sẽ phá vỡ code hiện có, nên nó vẫn giữ nguyên như vậy.
Kiểm tra null trực tiếp bằng value === null.
Kiểm tra một mảng bằng Array.isArray(value). Nó chỉ trả về true khi bạn truyền vào một mảng, nên nó phân biệt mảng khỏi object và null.
Loại bỏ 2 cái đó trước, và bất cứ gì còn lại là "object" chính là "một object không phải mảng cũng không phải null".
object từ typeof. Mỗi giá trị nhận một kiểm tra khác nhau. Cái nào không phải 2 cái kia là một object.const shipping = null;
const cart = ["Mouse"];
const order = { orderId: "ORD-6033" };
// typeof trả về cùng kết quả cho cả 3
console.log(typeof shipping); // object
console.log(typeof cart); // object
// Kiểm tra null trực tiếp bằng ===
console.log(shipping === null); // true
// Kiểm tra một mảng bằng Array.isArray
console.log(Array.isArray(cart)); // true
console.log(Array.isArray(order)); // false
// Có phải một object không phải mảng cũng không phải null?
console.log(typeof order === "object" && order !== null && !Array.isArray(order)); // true
Loại Bỏ null Trước Khi Đọc Nội Dung Nó
Coi typeof value === "object" là điều kiện duy nhất trước khi đọc nội dung một giá trị, và nó dừng với TypeError ngay khi value là null. typeof để null trượt qua thẳng, nên kiểm tra value !== null trước, hoặc dùng optional chaining, như value?.city.
Một Chuỗi Có Thể Coi Là Số Không — Number và Number.isNaN
Một số lượng hay một số tiền đến từ một form trông giống chữ số, nhưng kiểu của nó là chuỗi. Dùng nó trong một phép tính mà không kiểm tra nó có thể coi là số hay không trước, và một giá trị như "12px" chảy thẳng vào phép tính và tạo ra NaN.
Cái nói đến ở đây không phải chính kiểu, mà là nó có chuyển đổi được không.
Chuyển đổi bằng Number(input) và kiểm tra kết quả có phải NaN không bằng Number.isNaN(result) đã nói ở bài về chuyển đổi kiểu. Điều đáng tách riêng khỏi việc kiểm tra kiểu ở đây là đây là kiểm tra nội dung, không phải kiểm tra kiểu.
Cả "9800" lẫn "abc" đều có cùng typeof là "string" — liệu một thứ có hoạt động như một số lượng hay không không thể biết từ kiểu của nó.
Cạm bẫy là một chuỗi rỗng. Number("") trả về 0, không phải NaN, nên một trường form chưa điền trượt qua như "một giá trị nhập hợp lệ, số lượng 0".
Để loại bỏ một chuỗi rỗng, kiểm tra input !== "" trước khi chuyển đổi.
NaN. Chỉ chuỗi rỗng trở thành 0, nên loại bỏ nó trước khi chuyển đổi.console.log(Number("9800")); // 9800
console.log(Number("abc")); // NaN
console.log(Number("")); // 0 (không phải NaN)
// Kiểm tra kết quả đã chuyển đổi có phải NaN không
console.log(Number.isNaN(Number("abc"))); // true
console.log(Number.isNaN(Number("9800"))); // false
// Một chuỗi rỗng trượt qua thành 0
console.log(Number.isNaN(Number(""))); // false
Chọn Đúng Kiểm Tra — Bảng Tra Cứu Nhanh
Có nhiều hơn 1 cách viết một kiểm tra kiểu. Một số kiểu chỉ typeof là đủ để phân biệt, số khác cần thêm một kiểm tra trên nền kết quả typeof trả về, và liệu nội dung của một chuỗi có dùng được như số hay không là một kiểm tra hoàn toàn tách biệt khỏi kiểu. Chọn cách viết dựa trên cái bạn đang muốn xác nhận.
typeof một mình quyết định mọi kiểu trừ object. Chuyển sang một kiểm tra khác khi object trả về, hoặc khi bạn cần nhìn vào bên trong một chuỗi.| Cần Kiểm Tra Gì | Viết Thế Nào | Lưu Ý |
|---|---|---|
| Nó có phải chuỗi, số, hay boolean? | typeof value === "string", v.v. | Hoạt động trực tiếp |
| Một giá trị có bị thiếu không? | value === undefined | typeof cũng dùng được. Chỉ để đặt mặc định, dùng ?? (bài 9) |
| Nó có phải null không? | value === null | typeof trả về object cho cái này |
| Nó có phải mảng không? | Array.isArray(value) | typeof trả về object cho cái này |
| Nó có phải object thuần không? | typeof là object, trừ null và mảng | Nối 3 điều kiện bằng && |
| Nó có thể coi là số không? | Chuyển bằng Number, rồi kiểm tra bằng Number.isNaN | Chuỗi rỗng thành 0 |
Kiểm tra kiến thức
Hãy trả lời từng câu hỏi một.
Câu 2Cái nào trong số này kiểm tra một thứ có phải mảng không?
Câu 3Number("") trả về gì?