ไวยากรณ์การเรียกใช้ฟังก์ชันทันที


110

มีตัวเลือกJSLintซึ่งเป็นหนึ่งใน The Good Parts ที่ "[ต้อง] parens สำหรับการเรียกใช้ทันที" ซึ่งหมายความว่าการก่อสร้าง

(function () {

  // ...

})();

จะต้องเขียนเป็น

(function () {

  // ...

}());

คำถามของฉันคือ - ใครสามารถอธิบายได้ว่าเหตุใดรูปแบบที่สองนี้จึงถือว่าดีกว่า มีความยืดหยุ่นมากขึ้นหรือไม่? เกิดข้อผิดพลาดน้อยกว่า? รูปแบบแรกมีข้อดีอย่างไร?


ตั้งแต่ถามคำถามนี้ฉันได้เข้าใจถึงความสำคัญของการมีความแตกต่างทางภาพที่ชัดเจนระหว่างค่าฟังก์ชันและค่าของฟังก์ชัน พิจารณากรณีที่ผลลัพธ์ของการเรียกใช้ทันทีอยู่ทางขวามือของนิพจน์การมอบหมาย:

var someVar = (function () {

  // ...

}());

แม้ว่าวงเล็บด้านนอกสุดจะไม่จำเป็นทางไวยากรณ์ แต่วงเล็บเปิดจะให้การบ่งชี้ล่วงหน้าว่าค่าที่กำหนดไม่ใช่ฟังก์ชันเอง แต่เป็นผลลัพธ์ของฟังก์ชันที่เรียกใช้

สิ่งนี้คล้ายกับคำแนะนำของ Crockford เกี่ยวกับการใช้ตัวพิมพ์ใหญ่ของฟังก์ชันตัวสร้าง - มีไว้เพื่อใช้เป็นสัญญาณภาพสำหรับทุกคนที่ดูซอร์สโค้ด


ขอบคุณที่ชี้ให้เห็น ฉันไม่เคยพบวิธีกำจัดข้อความเตือนของ JSLint "โปรดใช้ความระมัดระวังเมื่อสร้างฟังก์ชันภายในลูป" ฉันระมัดระวังและปิดฟังก์ชั่นนี้ แต่ JSLint ยังคงบ่น ตอนนี้ฉันรู้แล้วว่ามันคิดว่าฉันใช้รูปแบบที่สอง
viam0Zah


ฉันทำมัน "ผิด" มาตลอด และเมื่อฉันพูดว่า "ตลอดเวลา" ฉันเขียน JavaScript มาตั้งแต่ปี 1995
Dave Land

คำตอบ:


73

จากคู่มือการประชุมสไตล์ของ Douglass Crockford : (ค้นหาคำว่า "invoked ทันที")

เมื่อต้องการเรียกใช้ฟังก์ชันทันทีนิพจน์การเรียกใช้ทั้งหมดควรถูกรวมไว้ใน parens เพื่อให้ชัดเจนว่าค่าที่สร้างขึ้นนั้นเป็นผลมาจากฟังก์ชันไม่ใช่ฟังก์ชันเอง

โดยพื้นฐานแล้วเขารู้สึกว่ามันทำให้ความแตกต่างระหว่างค่าฟังก์ชันและค่าของฟังก์ชันชัดเจนยิ่งขึ้น ดังนั้นมันจึงเป็นเรื่องเกี่ยวกับโวหารไม่ใช่ความแตกต่างที่สำคัญในตัวโค้ดเอง

ข้อมูลอ้างอิงที่อัปเดต PPT เก่าไม่มีอยู่แล้ว


1
ฉันดีใจที่ได้อ่านสิ่งนี้ ฉันเพิ่งอ่าน Javascript: The Good Parts เสร็จแล้วและสิ่งที่ฉันคิดอยู่เสมอคือการกำหนดผลลัพธ์ของการเรียกใช้ฟังก์ชันนั้นเป็นไวยากรณ์ที่แย่มากเพราะคุณต้องดูบรรทัดแรกและบรรทัดสุดท้ายเพื่อทำความเข้าใจว่าเกิดอะไรขึ้น เขาไม่ใช้ผ้าห่อตัวในหนังสือ แต่ฉันเห็นว่าทำไมเขาถึงแนะนำพวกเขา
Skilldrick

2
@altCognito คุณสามารถให้ลิงก์ใหม่สำหรับ PPT ได้หรือไม่
th1rdey3

1
ฉันดูผ่านเว็บ แต่ยังไม่พบสำเนาของ PPT นั้น
Forethinker

1
ฉันไม่พบ PPT ดั้งเดิม แต่ฉันสามารถหาจุดเดียวกันที่พบในคู่มือการประชุมจาวาสคริปต์ของเขา
cgp

archive.org มีไหม
John Greene

2

ทันทีที่เรียกว่าฟังก์ชั่นไม่ระบุตัวตนถูกห่อไว้ใน parens เนื่องจาก:

  1. เป็นนิพจน์ของฟังก์ชันและการปล่อยให้ parens ออกจะทำให้ถูกตีความว่าเป็นการประกาศฟังก์ชันซึ่งเป็นข้อผิดพลาดทางไวยากรณ์

  2. นิพจน์ฟังก์ชันไม่สามารถเริ่มต้นด้วยฟังก์ชันคำ

  3. เมื่อกำหนดนิพจน์ฟังก์ชันให้กับตัวแปรฟังก์ชันนั้นจะไม่ถูกส่งกลับค่าที่ส่งคืนของฟังก์ชันจะถูกส่งกลับดังนั้น parens จึงประเมินสิ่งที่อยู่ภายในและสร้างมูลค่าเมื่อฟังก์ชันถูกเรียกใช้งานและ parens ต่อท้าย..}()ทำให้ฟังก์ชันดำเนินการทันที


ดาธานคุณกำลังตอบคำถามอื่น คุณถูกต้องที่บางครั้งวงเล็บปิดมีความจำเป็นทางวากยสัมพันธ์เพื่อให้ตัววิเคราะห์สามารถแยกแยะนิพจน์ฟังก์ชันจากการประกาศฟังก์ชันได้ แต่คำถามของฉันเกี่ยวกับตำแหน่งของวงเล็บคำเรียกร้อง คุณจุดที่สามไม่ถูกต้อง ในกรณีนั้นไม่จำเป็นต้องใส่วงเล็บปิด
Bobby Eickhoff

ฉันกำลังตอบตัวอย่างแรกของคุณซึ่งฟังก์ชันที่เรียกทันทีว่าไม่ระบุตัวตนไม่ได้ถูกกำหนดให้กับตัวแปรดังนั้นวงเล็บจึงมีความจำเป็นทางไวยากรณ์ด้วยเหตุผล 2 ประการแรก เหตุผลประการที่ 3 คือการคืนสถานะสิ่งที่คุณพูด: "วงเล็บเปิดจะเป็นการบ่งชี้ล่วงหน้าว่าค่าที่กำหนดไม่ใช่ฟังก์ชัน แต่เป็นผลจากการเรียกใช้ฟังก์ชัน" แต่ฉันเดาว่ามันไม่ชัดเจน
Dathan

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.