JavaScript
Type Coercion
Numeric coercion
ดูว่า JavaScript แปลง string ที่เหมือนตัวเลขเป็น number เมื่อใช้ -, *, / อย่างไร และรู้จัก NaN เมื่อแปลงไม่สำเร็จ
`-`, `*`, `/` พยายามแปลงค่าเป็น number
`Numeric coercion` คือการที่ JavaScript แปลงค่าให้เป็น number ก่อนคำนวณ operator อย่าง `-`, `*`, และ `/` ไม่มีหน้าที่ต่อ string จึงพยายามแปลง string ที่ดูเหมือนเลขให้เป็น number
| โค้ด | ผลลัพธ์ | เหตุผล |
|---|---|---|
| "12" - 2 | 10 | `"12"` ถูกแปลงเป็น number |
| "6" * 3 | 18 | `"6"` ถูกแปลงเป็น number |
| "20" / 5 | 4 | `"20"` ถูกแปลงเป็น number |
| "hello" * 2 | NaN | แปลงเป็น number ไม่ได้ |
`NaN` ย่อมาจาก Not a Number หมายถึง JavaScript พยายามคำนวณเป็นตัวเลขแล้วไปต่อไม่ได้ `typeof NaN` ได้ผลลัพธ์เป็น `"number"` — เรื่องนี้อาจทำให้สับสนเพราะชื่อบอกว่า Not a Number แต่ชนิดข้อมูลกลับเป็น number
`+` ทำ string coercion ไม่ใช่ numeric coercion
`+, -, *, /` ดูเหมือน arithmetic operators ชุดเดียวกัน แต่จริง ๆ `+` กับ `-, *, /` มีกฎการแปลงชนิดข้อมูลต่างกัน
- `-`, `*`, `/` แปลง string เป็น number ก่อนคำนวณ (numeric coercion)
- `+` แปลง number เป็น string เมื่อมี string อยู่ฝั่งใดฝั่งหนึ่ง (string coercion)
- ดังนั้น `"5" + 2` ได้ `"52"` แต่ `"5" - 2` ได้ `3`
console.log("5" + 2); // "52" — + ต่อ string
console.log("5" - 2); // 3 — - แปลงเป็น number
console.log("5" * 2); // 10 — * แปลงเป็น number
console.log("5" / 2); // 2.5 — / แปลงเป็น numberนี่คือสาเหตุหลักที่ทำให้ type coercion สร้าง bug ได้ง่าย เพราะ `+` มีสองหน้าที่ใน JavaScript: บวกเลข กับ ต่อข้อความ
ใช้ `String()` แปลง number กลับเป็น string
บางครั้งต้องการแปลงผลลัพธ์ที่เป็น number กลับไปเป็น string เพื่อแสดงผลร่วมกับข้อความ ใช้ `String()` เช่นเดียวกับที่ใช้ `Number()` และ `Boolean()` — เป็น explicit coercion ที่ตั้งใจแปลง
let score = 95;
let scoreText = String(score);
console.log(scoreText); // "95"
console.log(typeof scoreText); // "string"
console.log("Score: " + scoreText); // "Score: 95"ข้อควรระวัง
- `NaN` เท่ากับอะไรก็ไม่เป็น `true` แม้แต่ `NaN === NaN` ก็เป็น `false` — ใช้ `Number.isNaN()` เพื่อตรวจสอบ
- `null` แปลงเป็น `0` เมื่อใช้ numeric coercion เช่น `null * 1` ได้ `0` — ผิดจากที่หลายคนคาด
- `undefined` แปลงเป็น `NaN` เมื่อใช้ numeric coercion เช่น `undefined + 1` ได้ `NaN`
- string ว่าง `""` แปลงเป็น `0` ด้วย numeric coercion เช่น `Number("")` ได้ `0`
- string ที่มี whitespace ล้วน เช่น `" "` ก็แปลงเป็น `0` ด้วย `Number()`
- `+` หน้าค่าเดี่ยว เช่น `+"42"` ก็ทำ numeric coercion เช่นกัน ได้ `42` แต่ทำให้โค้ดอ่านยาก