Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

เกิดอะไรขึ้นถ้า Semicolon วางผิดที่ใน JavaScript (ASI Pitfalls)

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)

  1. JavaScript แทรก ; ก่อน } (Closing Brace)
  2. JavaScript แทรก ; หลัง Statement ที่จบบรรทัด (Line Terminator) และ Token ถัดไปไม่ต่อเนื่องได้ (เช่น return, throw, break, continue, ++, --, yield, await)
  3. 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"