Dấu chấm phẩy hàng đầu trong các thư viện JavaScript làm gì?


156

Trong một số thư viện JavaScript, tôi đã thấy ký hiệu này ngay từ đầu:

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

Trong khi tôi hoàn toàn thoải mái với cú pháp "hàm thực thi ngay lập tức"

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

Tôi đã tự hỏi những dấu chấm phẩy hàng đầu là gì. Tất cả những gì tôi có thể nghĩ ra là nó là một loại bảo hiểm. Đó là, nếu thư viện được nhúng vào mã lỗi khác, nó sẽ đóng vai trò là "tuyên bố cuối cùng kết thúc ở đây với kiểu tăng tốc mới nhất".

Nó có chức năng nào khác không?


Câu trả lời:


140

Nó cho phép bạn ghép một cách an toàn một số tệp JavaScript thành một, để phục vụ nhanh hơn dưới dạng một yêu cầu HTTP.


16
Nhưng nó sẽ không cần thiết, nếu tất cả các tệp sẽ được mã hóa chính xác, phải không?
Boldewyn

8
Không: Trong ví dụ của bạn, bạn sẽ nhận được (function(){...})()(function(){...})().
Aaron Digulla

8
Điều đó có nghĩa là tôi đã 'mã hóa chính xác', rằng mọi thư viện đều kết thúc với số lượng dấu chấm phẩy chính xác ...
Boldewyn

6
Vâng Boldewyn, nhưng đơn giản là không phải vậy.
Mathias Bynens

13
Hai tệp được mã hóa xấu sẽ không phù hợp chỉ bởi thực tế là tệp thứ ba chứa bản sửa lỗi bẩn này. Tại sao kết nối không thể thêm dấu chấm phẩy giữa các tệp trong kết quả?
Dávid Horváth

30

Câu trả lời tốt nhất đã thực sự được đưa ra trong câu hỏi, vì vậy tôi sẽ chỉ viết nó xuống đây cho rõ ràng:

Dẫn đầu ;trước các biểu thức hàm được gọi ngay lập tức là ở đó để ngăn ngừa lỗi khi nối thêm tệp trong quá trình nối vào tệp chứa biểu thức không được kết thúc đúng với a ;.

Thực hành tốt nhất là chấm dứt biểu thức của bạn bằng dấu chấm phẩy, nhưng cũng sử dụng dấu chấm phẩy hàng đầu như một biện pháp bảo vệ.


Tại sao cũng chấm dứt biểu thức của bạn bằng dấu chấm phẩy, nếu bạn đang sử dụng dấu chấm phẩy phòng thủ? Hoặc là bạn có cơ hội dựa vào dấu chấm phẩy ở cuối mỗi dòng hoặc bạn sử dụng dấu chấm phẩy phòng thủ. Làm cả hai làm cho mọi người kết luận không chính xác rằng có một lý do để làm cả hai. Lời khuyên để sử dụng dấu chấm phẩy phòng thủ là tốt; lời khuyên để thay thế mọi trường hợp "\n"với ";\n"không có ý nghĩa.
Vladimir Kornea

4
@VladimirKornea: bởi vì bạn không phải lúc nào cũng chỉ sử dụng các thư viện của riêng mình :)
jvenema

@jvenema Tôi không biết tại sao bạn nghĩ rằng điều đó làm nên sự khác biệt.
Vladimir Kornea 16/2/2016

6
Bởi vì bạn không thể dựa vào mã của người khác theo các quy ước của bạn. Mã phòng thủ và sau đó bạn không phải.
jvenema

1
@VladimirKornea Bạn cũng có thể nghĩ đó là phòng thủ, nếu bạn muốn - nó bảo vệ chống lại mã của người khác không luôn bắt đầu bằng dấu chấm phẩy phòng thủ.
Nathan Hinchey

26

Nói chung, nếu một câu lệnh bắt đầu bằng (, [, /, +, hoặc -, có khả năng nó có thể được hiểu là sự tiếp nối của câu lệnh trước. Các câu lệnh bắt đầu bằng /, + và - khá hiếm trong thực tế , nhưng các câu lệnh bắt đầu bằng (và [hoàn toàn không phổ biến, ít nhất là trong một số kiểu lập trình JavaScript. Một số lập trình viên muốn đặt dấu chấm phẩy phòng thủ ở đầu bất kỳ câu lệnh nào để nó sẽ tiếp tục hoạt động chính xác ngay cả khi câu lệnh trước khi nó được sửa đổi và một dấu chấm phẩy chấm dứt trước đó đã bị xóa:

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

Nguồn:

JavaScript: Hướng dẫn dứt khoát, ấn bản thứ 6


9

Điều này được gọi là một dấu chấm phẩy hàng đầu.

Mục đích chính của nó là để bảo vệ chính nó khỏi mã trước đó được đóng không đúng cách, có thể gây ra vấn đề. Dấu chấm phẩy sẽ ngăn điều này xảy ra. Nếu mã trước đó được đóng không đúng cách thì dấu chấm phẩy của chúng tôi sẽ sửa lỗi này. Nếu nó được đóng lại đúng cách thì dấu chấm phẩy của chúng ta sẽ vô hại và sẽ không có tác dụng phụ.


7

Câu trả lời một dòng là ghép nối nhiều tệp JavaScript một cách an toàn. Sử dụng dấu chấm phẩy không gây ra vấn đề gì.

Giả sử bạn có nhiều chức năng:

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

Về nối, nó có thể trông giống như:

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

Nhưng nếu bạn thêm dấu chấm phẩy trước hàm thì nó sẽ trông như sau:

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

Vì vậy, bằng cách thêm một ; , cần phải cẩn thận nếu bất kỳ biểu thức nào không được kết thúc đúng.

Ví dụ 2

Giả sử bạn có tệp JavaScript có biến:

var someVar = "myVar"

Một tệp JavaScript khác có một số chức năng:

(function(){})()

Bây giờ trên concaten nó sẽ trông giống như

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

Với dấu chấm phẩy, nó sẽ trông như sau:

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

4

Thật tốt khi bạn thu nhỏ mã JavaScript. Nó ngăn ngừa lỗi cú pháp bất ngờ.


Như thế nào? Dấu chấm phẩy có bất kỳ ý nghĩa nào đối với mã sau đây không hay chỉ là mã lỗi giả định được hợp nhất trước thư viện thực tế?
Boldewyn

Trong các mã đó, không có ý nghĩa đặc biệt, nhưng khi mã đó ở giữa các mã khác và khi bạn rút gọn nó thành một dòng, có thể có các lỗi không mong muốn, như (1) dấu chấm phẩy bị thiếu trong các dòng trước, (1 ) trước đó cũng là các hàm vì vậy nó sẽ là () () () (), khi gặp lỗi, khó gỡ lỗi, chúng tôi không thể nói nó có lỗi, bởi vì trước khi giảm thiểu hoạt động tốt.
BẠN

1
Nhưng chắc chắn đó là trách nhiệm của người khai thác để xử lý việc này một cách chính xác. Là công cụ khai thác lỗi là tiêu chuẩn hiện nay?
Vladimir Kornea
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.