JavaScript
Number Methods
Number.isNaN
เรียนรู้ `Number.isNaN()` สำหรับตรวจสอบว่าเป็น `NaN` จริง ๆ โดยไม่แปลง type — แตกต่างจาก global `isNaN()` ที่มีปัญหา coercion
Number.isNaN คืออะไร และต่างจาก global isNaN อย่างไร
`Number.isNaN(value)` คือ static method ที่เช็กว่า `value` เป็น `NaN` หรือไม่ โดยตรวจสอบแบบตรงไปตรงมา — **ไม่แปลง type ก่อน** JavaScript มี `isNaN()` แบบ global มาก่อน แต่ global `isNaN()` มีปัญหา: มันจะแปลง argument เป็น number ก่อนเสมอ ทำให้ `isNaN("hello")` ได้ `true` ทั้งที่ `"hello"` ไม่ใช่ `NaN` — มันเป็น string ที่แปลงเป็น number ไม่ได้ต่างหาก `Number.isNaN()` ถูกเพิ่มเข้ามาใน ES6 (ES2015) เพื่อแก้ปัญหานี้ — มันจะคืน `true` เฉพาะเมื่อค่าเป็น `NaN` จริง ๆ เท่านั้น
// isNaN() — แปลงเป็น number ก่อนเช็ก
console.log(isNaN(NaN)); // true ✅
console.log(isNaN("hello")); // true ❌ string ไม่ใช่ NaN!
console.log(isNaN("123")); // false ✅ (coerce ได้เป็น 123)
console.log(isNaN(undefined)); // true ❌ undefined ไม่ใช่ NaN!
// Number.isNaN() — เช็กว่าเป็น NaN จริง ๆ เท่านั้น
console.log(Number.isNaN(NaN)); // true ✅
console.log(Number.isNaN("hello")); // false ✅ string ไม่ใช่ NaN
console.log(Number.isNaN("123")); // false ✅
console.log(Number.isNaN(undefined)); // false ✅
console.log(Number.isNaN(42)); // false ✅global isNaN() แปลงค่าเป็น number ก่อน → ทำให้ "hello" ถูกมองว่าเป็น NaN แต่ Number.isNaN() ตรวจสอบตรง ๆ → "hello" ไม่ใช่ NaN
กฎสำคัญของ Number.isNaN — ใครได้ true บ้าง
`Number.isNaN()` มีกฎง่ายมาก: จะคืน `true` ก็ต่อเมื่อค่าเป็น `NaN` จริง ๆ เท่านั้น ทุกอย่างอื่นคืน `false` นี่คือข้อแตกต่างสำคัญจาก global `isNaN()` — ไม่มี coercion, ไม่มี surprise, ตรวจสอบแบบ "type-safe" ค่าที่ทำให้ `Number.isNaN()` คืน `true`: `NaN`, ผลลัพธ์จากการคำนวณที่ผิดพลาด (`0/0`, `Infinity - Infinity`), หรือ `Number("abc")`
// === true: ค่าที่เป็น NaN จริง ๆ ===
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN(0 / 0)); // true — ผลลัพธ์เป็น NaN
console.log(Number.isNaN(Infinity * 0)); // true — ผลลัพธ์เป็น NaN
console.log(Number.isNaN(Number("abc"))); // true — แปลง string ไม่ได้
// === false: ทุกอย่างที่ไม่ใช่ NaN ===
console.log(Number.isNaN("NaN")); // false — string "NaN" ไม่ใช่ NaN
console.log(Number.isNaN(undefined)); // false — undefined ไม่ใช่ NaN
console.log(Number.isNaN(null)); // false — null ไม่ใช่ NaN
console.log(Number.isNaN({})); // false — object ไม่ใช่ NaN
console.log(Number.isNaN(true)); // false — boolean ไม่ใช่ NaN
console.log(Number.isNaN(Infinity)); // false — Infinity ไม่ใช่ NaN- Number.isNaN(NaN) → true เสมอ และเป็นค่าเดียวที่ได้ true
- ค่าที่เกิดจากคำนวณผิดพลาด (0/0, Infinity * 0) ก็เป็น NaN จึงได้ true
- ไม่มีการแปลง type — string, undefined, null, object ทั้งหมดได้ false
- Number.isNaN("NaN") → false — string ชื่อ "NaN" ไม่ใช่ค่า NaN
เมื่อไหร่ควรใช้ Number.isNaN
ใช้ `Number.isNaN()` ทุกครั้งที่ต้องการตรวจสอบว่าผลลัพธ์เป็นตัวเลขที่ใช้งานได้จริงหรือไม่ — โดยเฉพาะเมื่อรับค่าจากผู้ใช้, API, หรือผลลัพธ์จาก `parseInt()` / `parseFloat()` ในทางปฏิบัติ: ถ้าคุณแปลง string เป็น number แล้วอยากรู้ว่าสำเร็จหรือไม่ ให้ใช้ `Number.isNaN()` หลัง `Number()` — อย่าใช้ global `isNaN()` เพราะมันจะบอกว่า `undefined` และ `{}` ก็เป็น NaN ซึ่งไม่ถูกต้อง
// รับค่าจากผู้ใช้
const userInput = " 42 ";
const parsed = Number(userInput.trim());
// ✅ ใช้ Number.isNaN() ตรวจสอบ — แม่นยำ
if (Number.isNaN(parsed)) {
console.log("❌ ไม่ใช่ตัวเลขที่ถูกต้อง");
} else {
console.log("✅ ตัวเลขคือ", parsed);
}
// ❌ อย่าใช้ isNaN() — เพราะให้ผลผิดกับบางค่า
// isNaN(null) → false (เพราะ null → 0)
// isNaN(" ") → false (เพราะ " " → 0)
// ตรวจสอบผลลัพธ์การคำนวณ
function divide(a, b) {
const result = a / b;
if (Number.isNaN(result)) {
console.log("❌ ผลลัพธ์ไม่ใช่ตัวเลข (อาจเป็น 0/0)");
return null;
}
return result;
}
console.log(divide(10, 0)); // Infinity — ไม่ใช่ NaN ✅
console.log(divide(0, 0)); // null — 0/0 = NaN ❌| วิธีเช็ก NaN | แปลง type ก่อน? | isNaN("hello") | isNaN(undefined) | ใช้เมื่อไหร่ |
|---|---|---|---|---|
| isNaN() (global) | ✅ ใช่ — ทำให้เกิดผลลัพธ์ผิด | true ❌ | true ❌ | ❌ ไม่ควรใช้ — มี惊喜 (surprise) |
| Number.isNaN() | ❌ ไม่แปลง — ตรวจสอบตรง ๆ | false ✅ | false ✅ | ✅ ใช้เมื่อต้องการรู้ว่าเป็น NaN จริง ๆ |
| value !== value | ❌ ไม่แปลง — ใช้คุณสมบัติ NaN ≠ NaN | false ✅ | false ✅ | ✅ ใช้ได้ผลเหมือนกัน แต่อ่านยากกว่า |
สรุป: **ใช้ `Number.isNaN()` เสมอเมื่อต้องการตรวจสอบ NaN** — เลิกใช้ global `isNaN()` เพราะมัน misleading `value !== value` ก็ตรวจ NaN ได้เหมือนกันเพราะ NaN เป็นค่าเดียวใน JS ที่ไม่เท่ากับตัวเอง แต่ `Number.isNaN()` อ่านง่ายและสื่อความหมายชัดเจนกว่า