Trong JS, primitive number (500) và Number object (new Number(500)) khác hoàn toàn về so sánh và typeof.
Primitive Number — So sánh bằng giá trị
<script>
const x = 500;
const y = 500; // hoặc (500)
document.write(x === y + '<br>'); // true
document.write(typeof x + '<br>'); // "number"
document.write(typeof y + '<br>'); // "number"
</script>
Number Object — So sánh bằng tham chiếu
<script>
const x = 500;
const y = new Number(500); // Object wrapper
document.write(x === y + '<br>'); // false — khác reference!
document.write(typeof x + '<br>'); // "number"
document.write(typeof y + '<br>'); // "object"
</script>
Kết quả
false number object
Vấn đề lớn hơn: Object so với Object
const a = new Number(500);
const b = new Number(500);
document.write(a === b); // false — 2 object khác nhau
document.write(a == b); // true — loose equality unwrap value
document.write(+a === +b); // true — ép về primitive
Hành vi kỳ lạ khác
const numObj = new Number(0);
if (numObj) {
console.log('Truthy!'); // Chạy! Object luôn truthy
}
// nhưng
if (0) { ... } // Không chạy — 0 là falsy
Khi nào cần Number object?
Hầu như không bao giờ. Các method như toFixed(), toPrecision() hoạt động trên primitive nhờ auto-boxing:
(500).toFixed(2); // "500.00" — primitive tự động wrap thành Number tạm thời
Kết luận
- Luôn dùng primitive number (
const x = 500). - Tránh
new Number(),new String(),new Boolean()— gây bug so sánh, typeof, truthiness. - Nếu cần object wrapper: dùng
Object(500)(không new) — nhưng vẫn không khuyến khích.