2009-06-02 11 views
100

Có một tùy chọn JSLint, một trong The Good Parts trên thực tế, rằng "[đòi hỏi] parens xung quanh lời gọi ngay lập tức", có nghĩa rằng việc xây dựngchức năng ngay cú pháp gọi

(function() { 

    // ... 

})(); 

thay vào đó sẽ cần phải được viết như sau

(function() { 

    // ... 

}()); 

Câu hỏi của tôi là điều này - bất cứ ai có thể giải thích tại sao biểu mẫu thứ hai này có thể được coi là tốt hơn không? Nó có khả năng đàn hồi hơn không? Ít dễ bị lỗi hơn? Lợi thế nào nó có trên biểu mẫu đầu tiên?


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

var someVar = (function() { 

    // ... 

}()); 

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

Điều này tương tự như lời khuyên của Crockford về cách viết hoa của hàm dựng - nó có nghĩa là để phục vụ như một dấu hiệu trực quan cho bất kỳ ai nhìn vào mã nguồn.

+0

Cảm ơn cho trỏ này ra. Tôi chưa bao giờ tìm được cách để loại bỏ thông báo cảnh báo của JSLint "Hãy cẩn thận khi thực hiện các chức năng trong vòng lặp." Tôi đã cẩn thận, và đã đặt chức năng trong một đóng cửa 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. –

+0

Xem thêm [Khác biệt giữa (hàm() {})(); và function() {}();] (http://stackoverflow.com/q/423228/1048572) và có thể trùng lặp [Vị trí của dấu ngoặc đơn để tự động thực thi các hàm JavaScript ẩn danh?] (http://stackoverflow.com/ q/3384504/1048572) – Bergi

Trả lời

61

Từ Douglass Crockford style convention guide: (tìm kiếm cho "gọi ngay lập tức")

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

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

cập nhật tài liệu tham khảo, cũ PPT không còn tồn tại

+1

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

+2

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

+1

Tôi đã xem qua web nhưng tôi vẫn không thể tìm thấy bản sao của PPT – Forethinker

1

Ngay lập tức gọi Chức năng Anonymous được bọc nó trong dấu ngoặc vì:

  1. Họ là những biểu hiện chức năng và để lại dấu ngoặc ra sẽ gây ra nó phải được giải thích như một khai báo hàm là 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 biến, hàm trả về của hàm sẽ được trả về , do đó các phép đánh giá sẽ đánh giá những gì bên trong chúng và tạo ra một giá trị. khi chức năng được thực hiện và các dấu ngoặc đơn sau ..}() làm cho chức năng thực thi ngay lập tức.

+0

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

+0

Tôi đã trả lời ví dụ đầu tiên của bạn trong đó Chức năng ẩ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 cần thiết cho hai lý do đầu tiên. Lý do thứ 3 chỉ là khôi phục lại những gì bạn đã nói: "dấu ngoặc mở cho một dấu hiệu phía trước cho biết giá trị được gán không phải là chính hàm mà đúng hơn là kết quả của hàm được gọi." Nhưng tôi đoán nó không rõ ràng. – Dathan

-2

Hoặc, sử dụng:

void function() { 
... 
}()