ใน JavaScript เครื่องหมาย + ทำหน้าที่สองอย่าง ขึ้นอยู่กับ Data Type ของ Operand:
- Addition (บวกตัวเลข): ถ้า ทั้งสองฝั่งเป็น Number → คำนวณคณิตศาสตร์
- Concatenation (ต่อ String): ถ้า ฝั่งใดฝั่งหนึ่งเป็น String → แปลงอีกฝั่งเป็น String แล้วต่อกัน
ตัวอย่างเปรียบเทียบ
<script>
// Addition: ทั้งคู่เป็น Number
var val2 = 30 + 25;
document.write("30 + 25 = " + val2 + "<br>"); // "30 + 25 = 55"
// Concatenation: ด้านซ้ายเป็น Number, ขวาเป็น String
var val1 = 30 + "25";
document.write("30 + '25' = " + val1 + "<br>"); // "30 + '25' = 3025" (String)
// Concatenation: ด้านซ้ายเป็น String, ขวาเป็น Number
var val3 = "30" + 25;
document.write("'30' + 25 = " + val3 + "<br>"); // "'30' + 25 = 3025" (String)
// Concatenation: ทั้งคู่เป็น String
var val4 = "30" + "25";
document.write("'30' + '25' = " + val4 + "<br>"); // "'30' + '25' = 3025"
// Multiple Operands: ประเมินซ้ายไปขวา (Left-to-Right Associativity)
var val5 = 10 + 20 + "30"; // (10+20) -> 30 -> "30" + "30" -> "3030"
var val6 = "10" + 20 + 30; // "10" + 20 -> "1020" -> "1020" + 30 -> "102030"
var val7 = 10 + (20 + "30"); // 10 + "2030" -> "102030"
console.log(val5, val6, val7);
</script>
กฎการแปลง Type (Type Coercion Rules)
- ถ้า Operand ใด Operand หนึ่งเป็น String → อีกฝั่งถูกแปลงเป็น String → String Concatenation
- ถ้า ทั้งคู่เป็น Number (หรือ Boolean, null, Undefined ที่แปลงเป็น Number) → Numeric Addition
- Object (รวม Array, Date, Custom Object) → เรียก
valueOf()แล้วtoString()→ ได้ Primitive → ใช้กฎข้างต้น
// Object Coercion
[] + [] // "" (Empty String) -> [].toString() = ""
[] + {} // "[object Object]" -> [].toString() = "", {}.toString() = "[object Object]"
{} + [] // 0 (Block {} + Unary +[]) -> ใน Console/REPL แตกต่างจาก Script
[1,2] + [3,4] // "1,23,4" -> "1,2" + "3,4"
new Date() + "" // "Tue Oct 26 2023 ..." (String)
การบังคับให้เป็น Addition (Numeric)
// 1. Unary Plus (+)
+"25" + +"30" // 25 + 30 = 55
// 2. Number()
Number("25") + Number("30") // 55
// 3. parseInt / parseFloat
parseInt("25") + parseFloat("30.5") // 55.5
// 4. Bitwise OR (| 0) - แปลงเป็น Int32
"25" | 0 + "30" | 0 // 55 (แต่ระวัง Operator Precedence)
Template Literals (ES2015) - ทางเลือกที่ดีกว่าสำหรับ String
const a = 30, b = 25;
// แทนที่ "30" + "25" หรือ 30 + "25"
const result = `${a}${b}`; // "3025" (ชัดเจนว่าเป็น String)
const sum = `${a + b}`; // "55" (คำนวณก่อน แล้วค่อยแปลง String)
สรุป
| Operand A | Operand B | Result | Operation |
|---|---|---|---|
| Number | Number | Number | Addition |
| String | Any | String | Concatenation |
| Any | String | String | Concatenation |
| Object | Any | String (usually) | Concatenation (หลัง toString/valueOf) |
จำไว้: + กับ String = ต่อ String | + กับ Number เท่านั้น = บวกเลข | ใช้ Number(), +val, Template Literals เพื่อควบคุมพฤติกรรมให้ชัดเจน