อันตรายจาก IIFE ใน JavaScript
ลองพิจารณารหัสสองส่วนนี้
อันแรก:
let result = 1
+function() {
return 2;
}();
console.log(result);
อันที่สอง:
let result = 1;
+function() {
return 2;
}();
console.log(result);
รหัสสองส่วนนี้แทบจะเหมือนกันเลย
แต่ถ้านำไปรันผลลัพธ์จะแตกต่างกัน
รหัสแรกจะแสดงผลในคอนโซลเป็นตัวเลข 3
ส่วนอันที่สองเป็นตัวเลข 1
เหตุใดจึงแตกต่าง: ทั้งหมดเป็นเพราะ ในกรณีหนึ่งที่บรรทัดแรก ของโค้ดตอนท้ายไม่มีเครื่องหมายอัฒภาค แต่ในอีกกรณีหนึ่ง - มี
คุณอาจจะถาม: เป็นไปได้ยังไง ในเมื่อใน JavaScript เครื่องหมายอัฒภาคท้ายคำสั่งไม่ได้เป็น สิ่งที่จำเป็น! ที่จริงแล้วมันไม่ใช่แบบนั้นเสมอไป ลองมาหาคำตอบกันว่าจริงๆ แล้วเกิดอะไรขึ้น
โค้ดแรกสามารถเขียนใหม่ได้แบบนี้:
let result = 1 + function() {
return 2;
}();
console.log(result); // จะแสดง 3
ตอนนี้เห็นชัดเจนทันทีว่า เราได้
บวกหนึ่งเข้ากับผลลัพธ์จากการเรียกฟังก์ชันทันที
ซึ่งก็คือ 2 ดังนั้นผลลัพธ์สุดท้าย
จะได้ 3
แต่ถ้าหลังจากเลขหนึ่งเราใส่อัฒภาค โค้ดจะถูกตีความโดยตัวแปลภาษาอีกแบบ:
// คำสั่งแรก:
let result = 1;
// คำสั่งที่สอง:
+function() {
return 2;
}();
// คำสั่งที่สาม:
console.log(result); // จะแสดง 1
นั่นคือ การกำหนดค่าลงในตัวแปรและการเรียก ฟังก์ชันทันที จะกลายเป็นคนละคำสั่งกัน และทั้งหมดเป็นเพราะการมีอัฒภาค!
กลายเป็นว่า ในกรณีนี้การเรียกฟังก์ชัน
ทันทีไม่ได้ทำอะไรเลย - แค่
คืนค่าเลข 2 ไปสู่ความว่างเปล่า โดยที่
ไม่ส่งผลกระทบต่อตัวแปร result เลย
ลองมาหาคำตอบกันว่า แล้วทำไมเราถึง สามารถไม่เขียนอัฒภาคใน JavaScript ได้ สมมติว่าเรามีโค้ดแบบนี้โดยไม่มีอัฒภาค:
let result = 1 // ใน result จะได้ค่า 1
let test = 2 // ใน test จะได้ค่า 2
มันทำงานถูกต้อง เพราะตัวแปลภาษา ได้ใส่อัฒภาคท้ายแต่ละบรรทัดให้โดยอัตโนมัติ
แต่ลองดูโค้ดแบบนี้:
let result = 1
+ 2; // ใน result จะได้ค่า 3
ตอนนี้ อัฒภาคท้ายบรรทัดแรก จะไม่ถูกใส่อัตโนมัติ เพราะตัวแปลภาษา เข้าใจว่าคำสั่งของบรรทัดที่สอง - นั้นคือ ส่วนหนึ่งของคำสั่งบรรทัดแรก
แต่ถ้าเราใส่อัฒภาคเอง - ผลลัพธ์จะออกมาแตกต่างโดยสิ้นเชิง:
let result = 1; // ใน result จะได้ค่า 1
+ 2; // คำสั่งนี้ไม่ได้ทำอะไร แต่ก็ไม่เกิดข้อผิดพลาด
กลายเป็นว่า ตัวแปลภาษา จะใส่อัฒภาค โดยอัตโนมัติ เฉพาะเมื่อคำสั่งต่อไป ไม่ใช่ส่วนหนึ่งของคำสั่งก่อนหน้า
แล้วลองดูโค้ดนี้:
let result = 1
+function() {
return 2;
}();
console.log(result);
แน่นอน บรรทัดที่สอง - เป็นเพียงส่วนต่อ ของคำสั่งบรรทัดแรก และตัวแปลภาษาจะไม่ ใส่อัฒภาคโดยอัตโนมัติ นี่คือเหตุผลที่ ถ้าเราใส่อัฒภาคเองท้าย บรรทัดแรก - ผลลัพธ์ จะออกมาแตกต่างโดยสิ้นเชิง นี่บอกเราว่า ทางที่ดีที่สุดคือ ใส่อัฒภาคในตำแหน่งที่จำเป็นเสมอ เพื่อหลีกเลี่ยงปัญหา