JavaScript มีกลไก Automatic Semicolon Insertion (ASI) ที่แทรก Semicolon ให้อัตโนมัติในบางกรณี แต่การวาง Semicolon ผิดที่ (หรือขาดหายไปที่ไม่ควร) อาจทำให้โค้ดทำงานผิดปกติโดยไม่มี Error
ตัวอย่างคลาสสิก: Semicolon หลัง if Condition
<script>
var val1 = 10;
if (val1 == 15) { // Condition เป็น false
; // <-- Semicolon วางผิดที่ (Empty Statement)
document.write("Prints due to misplaced semi-colon: " + val1);
}
// ผลลัพธ์: "Prints due to misplaced semi-colon: 10" ❌
// เพราะ IF Body คือ Empty Statement (;) -> ทำไม่ทิด
// document.write() อยู่ *นอก* IF Block จึงรันเสมอ
var val2 = 10;
if (val2 == 15) { // Condition เป็น false
// ไม่มี Semicolon ที่นี่
document.write(val2); // อยู่ใน IF Block -> ไม่รัน ✅
}
</script>
กรณีอันตรายอื่นๆ ของ ASI
1. Return Statement แบบ Multi-line
function getObject() {
return // <-- ASI แทรก ; ที่นี่!
{
name: "John"
};
}
console.log(getObject()); // undefined ❌ (คืน undefined ไม่ใช่ Object)
// ✅ แก้: วาง { ตรงบรรทัดเดียวกับ return
function getObject() {
return {
name: "John"
};
}
2. IIFE / Function Expression ต่อจาก Statement
var x = 10
(function() { console.log("IIFE"); })()
// TypeError: 10 is not a function ❌
// JS อ่านว่า: var x = 10(function()...) -> เรียก 10 เป็น Function
// ✅ แก้: ใส่ ; ท้าย Statement ก่อนหน้า หรือ ใส่ ; หน้า (
var x = 10;
(function() { ... })();
// หรือ
var x = 10; (function() { ... })();
3. Array/Object Literal ต่อจาก Statement
var arr = [1,2,3]
[4,5,6].forEach(...) // TypeError: Cannot read property 'forEach' of undefined
// JS อ่านว่า: arr = [1,2,3][4,5,6] -> Property Access
// ✅ ใส่ ;
var arr = [1,2,3];
[4,5,6].forEach(...);
4. Template Literal ต่อจาก Expression
var name = "John"
`Hello ${name}` // Syntax Error หรือพฤติกรรมแปลก
// ✅ ใส่ ;
var name = "John";
`Hello ${name}`;
กฎ ASI เรียบง่าย (Simplified ASI Rules)
- JavaScript แทรก ; ก่อน
}(Closing Brace) - JavaScript แทรก ; หลัง Statement ที่จบบรรทัด (Line Terminator) และ Token ถัดไปไม่ต่อเนื่องได้ (เช่น
return,throw,break,continue,++,--,yield,await) - JavaScript ไม่แทรก ; หาก Token ถัดไปต่อเนื่องได้ (เช่น
(,[,/,+,-,*,%,,,., Template Literal)
Best Practice: ใช้ Semicolon เสมอ (Explicit Semicolons)
- ป้องกัน Bug ASI ทั้งหมด
- อ่านโค้ดง่ายขึ้น (ชัดเจนว่าจบ Statement ที่ไหน)
- Tools รองรับดี: ESLint (
semi: ["error", "always"]), Prettier, TypeScript - Standard Style Guides: Airbnb, Google, StandardJS (ทั้งคู่บังคับ Semicolon)
สรุป
Semicolon วางผิดที่ (หรือขาดหายไป) ทำให้ ASI แทรก Semicolon ผิดที่ → โค้ดทำงานผิด Logic (เช่น IF Body ว่าง, Return undefined, เรียก Number/Array เป็น Function) แก้ไขง่าย: ใส่ Semicolon ทุก Statement เสมอ และเปิด ESLint Rule semi: "error"