เซมิโคลอนชั้นนำในไลบรารี JavaScript ทำอะไร


156

ในห้องสมุด JavaScript หลายแห่งฉันเห็นสัญลักษณ์นี้ตั้งแต่แรก:

/**
 * Library XYZ
 */
;(function () {
  // ... and so on

ในขณะที่ฉันสบายอย่างสมบูรณ์กับไวยากรณ์

(function(){...})()

ฉันสงสัยว่าเซมิโคลอนชั้นนำคืออะไร ทั้งหมดที่ฉันสามารถทำได้คือประกัน นั่นคือถ้าไลบรารีถูกฝังในโค้ด buggy อื่น ๆ มันจะทำหน้าที่เป็น "คำสั่งสุดท้ายจบลงที่นี่ด้วยการชนแบบเร็ว"

มันมีฟังก์ชั่นอื่น ๆ บ้างไหม?


คำตอบ:


140

มันช่วยให้คุณเชื่อมไฟล์ JavaScript หลาย ๆ ไฟล์ให้เป็นไฟล์เดียวได้อย่างปลอดภัย


16
แต่มันจะไม่จำเป็นถ้าไฟล์ทั้งหมดจะถูกเข้ารหัสอย่างถูกต้องมันจะ?
Boldewyn

8
No: (function(){...})()(function(){...})()ในตัวอย่างของคุณคุณจะได้รับ
Aaron Digulla

8
ที่ผมหมายกับ 'รหัสอย่างถูกต้อง' ว่าทุกปลายห้องสมุดที่มีจำนวนเงินที่ถูกต้องของอัฒภาคต่อท้าย ...
Boldewyn

6
ใช่ Boldewyn แต่นั่นไม่ใช่กรณี
Mathias Bynens

13
ไฟล์ที่เข้ารหัสไม่ดีสองไฟล์จะไม่พอดีโดยข้อเท็จจริงที่ว่าไฟล์ที่สามมีการแก้ไขที่สกปรกนี้ ทำไมตัวเชื่อมต่อไม่สามารถเพิ่มเครื่องหมายอัฒภาคพิเศษระหว่างไฟล์ในผลลัพธ์ได้?
DávidHorváth

30

คำตอบที่ดีที่สุดนั้นเป็นจริงในคำถามดังนั้นฉันจะเขียนลงไปที่นี่เพื่อความชัดเจน:

ชั้นนำในด้านหน้าของฟังก์ชั่นการแสดงออกทันที-เรียกอยู่ที่นั่นเพื่อป้องกันข้อผิดพลาดเมื่อผนวกไฟล์ระหว่างเรียงต่อกันไปยังไฟล์ที่มีการแสดงออกไม่ยกเลิกอย่างถูกต้องด้วย;;

วิธีปฏิบัติที่ดีที่สุดคือยกเลิกนิพจน์ของคุณด้วยเครื่องหมายอัฒภาค แต่ใช้เซมิโคลอนชั้นนำเป็นตัวป้องกัน


ทำไมยกเลิกนิพจน์อัฒภาคของคุณด้วยถ้าคุณใช้เซมิโคลอนป้องกัน? ไม่ว่าคุณจะใช้โอกาสในการพึ่งพาเครื่องหมายอัฒภาคอยู่ที่ท้ายบรรทัดหรือคุณใช้เครื่องหมายอัฒภาค การทำทั้งสองอย่างทำให้ผู้คนสรุปไม่ถูกต้องว่ามีเหตุผลในการทำทั้งสองอย่าง คำแนะนำในการใช้อัฒภาคการป้องกันนั้นดี คำแนะนำยังเปลี่ยนทุกกรณีของ"\n"กับ";\n"ทำให้รู้สึกไม่
Vladimir Kornea

4
@VladimirKornea: เพราะคุณไม่เคยใช้เพียงห้องสมุดของคุณเอง :)
jvenema

@jvenema ฉันไม่รู้ว่าทำไมคุณถึงคิดว่าสร้างความแตกต่าง
Vladimir Kornea

6
เพราะคุณไม่สามารถพึ่งพารหัสของคนอื่นหลังจากการประชุมของคุณ รหัสป้องกันแล้วคุณไม่จำเป็นต้อง
jvenema

1
@VladimirKornea คุณสามารถคิดได้ว่าเป็นการป้องกันเช่นกันหากคุณต้องการ - มันเป็นการป้องกันรหัสของคนอื่นที่ไม่ได้เริ่มต้นด้วยเครื่องหมายอัฒภาคเพื่อการป้องกันเสมอไป
นาธาน Hinchey

26

โดยทั่วไปหากคำสั่งเริ่มต้นด้วย (, [, /, +, หรือ -, มีโอกาสที่จะสามารถตีความได้ว่าเป็นความต่อเนื่องของข้อความก่อนหน้านี้ข้อความที่เริ่มต้นด้วย /, + และ - ค่อนข้างหายากในทางปฏิบัติ แต่คำสั่งที่ขึ้นต้นด้วย (และ [ไม่ใช่เรื่องแปลกเลยอย่างน้อยก็ในบางรูปแบบของการเขียนโปรแกรม JavaScript) โปรแกรมเมอร์บางคนชอบที่จะใส่เซมิโคลอนการป้องกันไว้ที่จุดเริ่มต้นของคำสั่งใด ๆ เพื่อที่ว่ามันจะยังคงทำงานได้อย่างถูกต้อง ก่อนที่จะถูกแก้ไขและลบเครื่องหมายอัฒภาคก่อนหน้านี้:

var x = 0 // Semicolon omitted here
;[x,x+1,x+2].forEach(console.log) // Defensive ; keeps this statement separate

ที่มา:

JavaScript: The Definitive Guide, 6th edition


9

สิ่งนี้เรียกว่าเซมิโคลอนชั้นนำ

วัตถุประสงค์หลักคือเพื่อป้องกันตัวเองจากรหัสก่อนหน้าซึ่งถูกปิดอย่างไม่เหมาะสมซึ่งอาจทำให้เกิดปัญหา อัฒภาคจะป้องกันไม่ให้สิ่งนี้เกิดขึ้น หากรหัสก่อนหน้านี้ถูกปิดอย่างไม่เหมาะสมอัฒภาคของเราจะแก้ไขสิ่งนี้ หากปิดอย่างถูกต้องแล้วเครื่องหมายอัฒภาคของเราจะไม่เป็นอันตรายและจะไม่มีผลข้างเคียง


7

คำตอบเดียวคือการเชื่อมไฟล์ JavaScript หลาย ๆ ไฟล์อย่างปลอดภัย การใช้เครื่องหมายอัฒภาคไม่ได้ทำให้เกิดปัญหา

สมมติว่าคุณมีฟังก์ชั่นหลายอย่าง:

IIFE 1

(function(){
  // The rest of the code
})(); // Note it is an IIFE

IIFE 2

(function(){
   // The rest of the code
})(); // Note it is also an IIFE

ในการต่อข้อมูลอาจดูเหมือน:

(function(){})()(function(){})()

แต่ถ้าคุณเพิ่มเครื่องหมายอัฒภาคก่อนฟังก์ชันจะมีลักษณะดังนี้:

;(function(){})();(function(){})()

ดังนั้นโดยการเพิ่ม;มันจะดูแลถ้าการแสดงออกใด ๆ ไม่ได้ถูกยกเลิกอย่างถูกต้อง

ตัวอย่างที่ 2

สมมติว่าคุณมีไฟล์ JavaScript ที่มีตัวแปร:

var someVar = "myVar"

ไฟล์ JavaScript อื่นที่มีฟังก์ชั่นบางอย่าง:

(function(){})()

ตอนนี้มันจะมีลักษณะต่อกัน

var someVar = "myVar"(function(){})() // It may give rise to an error

ด้วยเซมิโคลอนมันจะมีลักษณะดังนี้:

var someVar = "myVar";(function(){})()

4

เป็นเรื่องที่ดีเมื่อคุณลดขนาดโค้ด JavaScript มันป้องกันข้อผิดพลาดทางไวยากรณ์ที่ไม่คาดคิด


เช่นอะไร? เครื่องหมายอัฒภาคมีความสำคัญใด ๆ สำหรับรหัสต่อไปนี้หรือว่าเป็นเพียงการใช้รหัสรถบั๊กกี้ที่รวมอยู่หน้าห้องสมุดจริง?
Boldewyn

ในรหัสนั้นเพียงอย่างเดียวไม่มีความหมายพิเศษ แต่เมื่อรหัสนั้นอยู่ตรงกลางของรหัสอื่น ๆ และเมื่อคุณย่อให้เหลือบรรทัดเดียวอาจมีข้อผิดพลาดที่ไม่คาดคิดเช่น (1) อัฒภาคหายไปในบรรทัดก่อนหน้า (1) ) ก่อนหน้านี้ยังมีฟังก์ชั่นดังนั้นมันจะเป็น () () () () เมื่อได้รับข้อผิดพลาดยากที่จะแก้ปัญหาเราไม่สามารถบอกว่ามันเป็นรถเพราะก่อนที่จะลดการทำงานได้ดี
คุณ

1
แต่แน่นอนมันเป็นความรับผิดชอบของ minifier ที่จะจัดการเรื่องนี้อย่างถูกต้อง ทุกวันนี้ minifiers buggy เป็นบรรทัดฐานหรือไม่?
Vladimir Kornea
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.