Giải mã câu đố JavaScript: Tại sao [] + {} ra "[object Object]" nhưng {} + [] lại ra 0?
Câu hỏi phỏng vấn kinh điển khiến nhiều dev bối rối Trong một buổi phỏng vấn JavaScript, người phỏng vấn mở console của trình duyệt lên và gõ: Rất nhiều bạn lập trình viên chỉ biết cười trừ và cho rằ…
☰ Mục lục bài viết (6 phần) Mở / Đóng mục lục
Câu hỏi phỏng vấn kinh điển khiến nhiều dev bối rối#
Trong một buổi phỏng vấn JavaScript, người phỏng vấn mở console của trình duyệt lên và gõ:
console.log([] + {}); // Kết quả: "[object Object]"
console.log({} + []); // Kết quả: 0 (trên một số môi trường REPL)
Rất nhiều bạn lập trình viên chỉ biết cười trừ và cho rằng: "JavaScript bị ngáo".
Thực tế, JavaScript không hề ngáo! Cả hai kết quả trên đều tuân thủ 100% theo các quy tắc nghiêm ngặt được định nghĩa trong đặc tả kỹ thuật ECMAScript (ToPrimitive và Type Coercion).
Giải mã chi tiết từng trường hợp#
1. Tại sao [] + {} ra "[object Object]"?#
Toán tử cộng + trong JavaScript hoạt động theo thứ tự:
- Nếu một trong hai toán hạng là Object, gọi phương thức nội bộ
ToPrimitive(hint: "default"). - Đối với mảng
[]: Gọi[].valueOf()$\rightarrow$ trả về mảng $\rightarrow$ không phải kiểu nguyên thủy $\rightarrow$ gọi tiếp[].toString()$\rightarrow$ trả về chuỗi rỗng"". - Đối với object
{}: Tương tự, gọi{}.toString()$\rightarrow$ trả về"[object Object]". - Khi có một toán hạng là chuỗi, toán tử
+trở thành phép nối chuỗi (String Concatenation):CODE"" + "[object Object]" === "[object Object]"
2. Tại sao {} + [] lại ra 0 trên Console?#
Khi bạn gõ {} + [] ở đầu một dòng lệnh trong Console hoặc Node REPL:
- Trình duyệt phân tích cặp dấu ngoặc nhọn
{}đứng đầu dòng KHÔNG PHẢI LÀ MỘT OBJECT, mà được hiểu là một Khối lệnh rỗng (Empty Block Statement)! - Khối lệnh rỗng này không làm gì cả và bị bỏ qua.
- Toàn bộ biểu thức còn lại chỉ là:
+ [](Toán tử cộng một ngôi - Unary Plus Operator). - Phép toán ép kiểu một ngôi biến mảng rỗng thành số:CODE
+ [] === + "" === 0 - Nếu bạn bọc trong dấu ngoặc tròn:
({} + []), trình duyệt sẽ hiểu{}là một Object và kết quả lại trở về"[object Object]"!
Bài học rút ra cho công việc thực tế#
- Tuyệt đối không dựa dẫm vào cơ chế ép kiểu ngầm (Implicit Coercion) của toán tử
+hoặc==. - Luôn sử dụng so sánh nghiêm ngặt
===. - Dùng TypeScript để bắt lỗi cộng object/array ngay từ lúc viết code.
Góc thảo luận#
Bạn đã từng gặp câu hỏi phỏng vấn nào "quái dị" về cơ chế ép kiểu ngầm của JavaScript chưa?
Xem thêm nội dung liên quan:
Thảo luận
1 phản hồi
Tham gia thảo luận
Bài liên quan trong #Frontend & Web UI
-
Xây dựng Voice AI Agent thời gian thực với WebRTC và Whisper Live: Độ trễ dưới 500ms
Lan Anh (Senior Frontend) · 💬 1 -
Tối ưu SEO cho Website Client-Side Rendering: Dynamic Rendering vs Static Export
Lan Anh (Senior Frontend) · 💬 1 -
Debug Memory Leak trong Single Page Application bằng Chrome DevTools Memory Profiler
Lan Anh (Senior Frontend) · 💬 1 -
Viết Component Accessible (a11y) chuẩn WAI-ARIA: Giúp website thân thiện với mọi đối tượng
Lan Anh (Senior Frontend) · 💬 1 -
Áp dụng Self-Consistency và Chain-of-Thought trong Prompting cho bài toán logic phức tạp
Minh Trí (AI Engineer) · 💬 1