Cú pháp gọi hàm ngay lập tức


110

Có một tùy chọn JSLint , một trong những The Good Parts trên thực tế, "[yêu cầu] quan sát xung quanh các lệnh gọi tức thì", nghĩa là việc xây dựng

(function () {

  // ...

})();

thay vào đó cần phải được viết là

(function () {

  // ...

}());

Câu hỏi của tôi là - bất cứ ai có thể giải thích tại sao hình thức thứ hai này có thể được coi là tốt hơn? Có kiên cường hơn không? Ít bị lỗi hơn? Nó có ưu điểm gì hơn so với hình thức đầu tiên?


Kể từ khi đặt câu hỏi này, tôi đã hiểu ra tầm quan trọng của việc có sự phân biệt trực quan rõ ràng giữa các giá trị của hàm và các giá trị của hàm. Hãy xem xét trường hợp kết quả của lệnh gọi ngay lập tức là phía bên phải của một biểu thức gán:

var someVar = (function () {

  // ...

}());

Mặc dù các dấu ngoặc đơn ngoài cùng là không cần thiết về mặt cú pháp, nhưng dấu ngoặc đơn mở đầu cung cấp một dấu hiệu phía trước rằng giá trị đang được gán không phải là bản thân hàm mà là kết quả của hàm được gọi.

Điều này tương tự như lời khuyên của Crockford liên quan đến việc viết hoa các hàm khởi tạo - nó được dùng như một gợi ý trực quan cho bất kỳ ai đang xem mã nguồn.


Cảm ơn vì đã chỉ ra điều này. Tôi chưa bao giờ tìm ra cách để loại bỏ thông báo cảnh báo của JSLint "Hãy cẩn thận khi tạo các hàm trong vòng lặp." Tôi đã cẩn thận và đã đóng hàm nhưng JSLint vẫn phàn nàn. Bây giờ tôi biết rằng nó giả định rằng tôi đã sử dụng mẫu thứ hai.
viam0Zah


Tôi đã làm nó "sai" suốt thời gian qua. Và khi tôi nói "mọi thời đại này," Tôi đã viết JavaScript kể từ năm 1995.
Dave Đất đai

Câu trả lời:


73

Từ hướng dẫn quy ước phong cách của Douglass Crockford : (tìm kiếm "được gọi ngay lập tức")

Khi một hàm được gọi ngay lập tức, toàn bộ biểu thức gọi phải được bao bọc trong các parens để rõ ràng rằng giá trị được tạo ra là kết quả của hàm chứ không phải chính hàm.

Vì vậy, về cơ bản, anh ấy cảm thấy nó phân biệt rõ ràng hơn giữa giá trị hàm và giá trị của hàm. Vì vậy, đó là một vấn đề về phong cách, không thực sự là một sự khác biệt đáng kể trong bản thân mã.

tham chiếu cập nhật, PPT cũ không còn tồn tại


1
Tôi rất vui vì tôi đã đọc nó. Tôi vừa mới đọc xong Javascript: The Good Parts, và điều tôi vẫn nghĩ là việc gán kết quả của việc gọi một hàm là cú pháp thực sự tồi, bởi vì bạn phải nhìn vào dòng đầu tiên và dòng cuối cùng để hiểu điều gì đang xảy ra. Anh ấy không sử dụng những cái gói trong cuốn sách, nhưng tôi thấy chính xác lý do tại sao anh ấy đề xuất chúng.
Skilldrick

2
@altCognito, bạn có thể cung cấp liên kết mới cho PPT không?
th1rdey3

1
Tôi nhìn qua web, nhưng tôi vẫn không thể tìm thấy một bản sao của PPT rằng
Forethinker

1
Tôi không thể tìm thấy PPT gốc, nhưng tôi có thể tìm thấy điểm tương tự được tìm thấy trong hướng dẫn quy ước javascript của anh ấy.
cgp

archive.org có nó không?
John Greene

2

Ngay lập tức được gọi là Hàm ẩn danh được gói gọn trong các parens vì:

  1. Chúng là các biểu thức hàm và việc bỏ dấu gạch ngang sẽ khiến nó được hiểu là một khai báo hàm là một lỗi cú pháp.

  2. Biểu thức hàm không thể bắt đầu bằng hàm từ.

  3. Khi gán biểu thức hàm cho một biến, bản thân hàm không được trả về, giá trị trả về của hàm được trả về, do đó các parens đánh giá những gì bên trong chúng và tạo ra một giá trị.khi hàm được thực thi, và dấu gạch ngang sẽ ..}()khiến hàm thực thi ngay lập tức.


Dathan, bạn đang trả lời một câu hỏi khác. Bạn nói đúng rằng các dấu ngoặc bao quanh đôi khi cần thiết về mặt cú pháp để trình phân tích cú pháp có thể phân biệt các biểu thức hàm với các khai báo hàm. Nhưng câu hỏi của tôi là về vị trí của dấu ngoặc đơn. Điểm thứ ba của bạn là không chính xác; trong trường hợp đó các dấu ngoặc bao quanh là không cần thiết.
Bobby Eickhoff

Tôi đang trả lời ví dụ đầu tiên của bạn trong đó Hàm ẩn danh được gọi ngay lập tức không được gán cho một biến và do đó dấu ngoặc đơn là cần thiết về mặt cú pháp vì 2 lý do đầu tiên. Lý do thứ ba chỉ là khôi phục những gì bạn thậm chí đã nói: "dấu ngoặc mở đầu cung cấp dấu hiệu phía trước rằng giá trị đang được gán không phải là chính hàm mà là kết quả của hàm được gọi." Nhưng tôi đoán nó không rõ ràng.
Dathan

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.