Một câu hỏi phỏng vấn có thể bắt đầu rất ngắn: Object.is(NaN, NaN) và NaN === NaN có cùng kết quả không? Câu trả lời tốt cần giải thích quy tắc, rồi phân biệt nó với việc so nội dung của object.
Bài dùng các đoạn JavaScript độc lập với React và trình duyệt, đối chiếu MDN ngày 27/10/2026. Snippet được chạy bằng Node.js 24.18.1 trong lượt biên tập. Đây là kiểm tra ngữ nghĩa với dữ liệu nhỏ, không phải đánh giá tốc độ của các phép so sánh.
1. Dự đoán rồi chạy các cặp giá trị
const pairs = [
['NaN', NaN, NaN],
['signed zero', +0, -0],
['different types', '0', 0],
['null/undefined', null, undefined],
['same number', 3, 3],
];
for (const [label, left, right] of pairs) {
console.log(label, left === right, Object.is(left, right));
}
Kết quả hai phép kiểm tra theo từng dòng:
| Cặp | === | Object.is |
|---|---|---|
| NaN với NaN | false | true |
| +0 với -0 | true | false |
| Chuỗi '0' với số 0 | false | false |
| null với undefined | false | false |
| Số 3 với số 3 | true | true |
Cả hai đều không ép chuỗi '0' thành số 0. Khác biệt về giá trị số ở đây là cách xử lý NaN và hai giá trị 0 khác dấu. Vì vậy, mô tả Object.is là “triple equals chặt hơn” dễ gây hiểu nhầm: nó trả true ở một ca mà triple equals trả false, nhưng cũng làm điều ngược lại ở ca khác.
2. NaN là một giá trị cần quy tắc riêng
NaN xuất hiện trong một số phép tính không tạo ra một số thông thường. Với ===, việc so nó với chính nó vẫn trả false. Với Object.is, hai giá trị NaN được coi là cùng giá trị theo quy tắc của hàm này.
Nếu mục tiêu của code là phát hiện một giá trị số có phải NaN hay không, hãy diễn đạt trực tiếp thay vì vô tình dùng một phép so sánh không đúng ý:
const invalid = Number('khong-phai-so');
console.log(invalid === NaN);
console.log(Object.is(invalid, NaN));
console.log(Number.isNaN(invalid));
console.log(Number.isNaN('khong-phai-so'));
Bốn kết quả lần lượt là false, true, true, false. Dòng cuối quan trọng: một chuỗi chưa được chuyển thành số không tự trở thành giá trị NaN chỉ vì nó không giống cách viết số. Khi review validation, hãy hỏi code đã ở tầng chuỗi nhập liệu hay tầng số đã parse.
3. +0 và -0 có thể nhìn giống nhau
Nhiều cách hiển thị khiến bạn chỉ thấy một số 0, nhưng dấu của zero có thể làm khác kết quả tính toán tiếp theo:
console.log(1 / +0);
console.log(1 / -0);
console.log(Object.is(+0, -0));
Kết quả là Infinity, -Infinity, false. Điều này giúp giải thích vì sao ngôn ngữ có một phép so sánh phân biệt hai giá trị. Không có nghĩa rằng mọi form số lượng hàng hóa phải giữ hai loại zero khác nhau; quy tắc chuẩn hóa dữ liệu vẫn do nghiệp vụ quyết định.
Trong câu trả lời phỏng vấn, đưa một phép tính nhỏ như trên sẽ rõ hơn việc chỉ nhớ bảng true/false. Sau đó nói rõ tình huống của ứng dụng có cần phân biệt dấu đó không, thay vì đề xuất đổi mọi === thành Object.is.
4. Object.is không so sánh sâu object
const first = {id: 1};
const alias = first;
const another = {id: 1};
console.log(Object.is(first, alias), first === alias);
console.log(Object.is(first, another), first === another);
Hai kết quả trên mỗi dòng lần lượt là true true và false false. Alias trỏ đến cùng object; another là một object khác dù có cùng thuộc tính. Tên “Object.is” không có nghĩa hàm duyệt từng khóa rồi so nội dung.
Nếu yêu cầu là xác định hai bản ghi có cùng ID, hãy so trường ID theo hợp đồng dữ liệu. Nếu yêu cầu là so nội dung lồng nhau, bạn cần định nghĩa cách xử lý array, ngày tháng, giá trị thiếu và các kiểu dữ liệu liên quan. Đó là một yêu cầu khác với identity.
Cách trả lời gọn trong buổi phỏng vấn
Bắt đầu bằng việc cả hai không thực hiện ép kiểu như loose equality. Nêu hai trường hợp khác nhau là NaN và signed zero. Cuối cùng dùng hai object cùng nội dung để chứng minh rằng cả hai vẫn dựa vào identity với object.
Người phỏng vấn có thể hỏi tiếp vì sao một phương thức tìm kiếm nhận ra NaN trong khi phép === không nhận ra. Khi ấy, cần đọc quy tắc so sánh mà chính API đó dùng, chẳng hạn SameValueZero; đừng suy luận mọi API đều dùng cùng một phép so sánh.
Kiểm tra và giới hạn
Hãy chạy các snippet rồi tự thêm boolean, string và object được tạo mới. Tránh dùng duy nhất output từ JSON serialization để quan sát những giá trị số đặc biệt, vì cách serialize không phải định nghĩa equality của ngôn ngữ.
Những ví dụ này chưa khảo sát mọi kiểu dữ liệu hoặc đưa ra một hàm deep equal. Điều cần mang vào công việc là chọn phép so sánh theo câu hỏi dữ liệu, đồng thời giải thích được trường hợp biên mà code đang giữ hay bỏ qua.

