Składnia natychmiastowego wywołania funkcji

110

Istnieje opcja JSLint , jedna z dobrych części, która „[wymaga] powiązań wokół natychmiastowych wywołań”, co oznacza, że ​​konstrukcja

(function () {

  // ...

})();

zamiast tego musiałby być zapisany jako

(function () {

  // ...

}());

Moje pytanie jest takie - czy ktoś może wyjaśnić, dlaczego tę drugą formę można uznać za lepszą? Czy jest bardziej odporny? Mniej podatne na błędy? Jaką ma przewagę nad pierwszą formą?


Odkąd zadałem to pytanie, zrozumiałem, jak ważne jest wyraźne wizualne rozróżnienie między wartościami funkcji a wartościami funkcji. Rozważmy przypadek, w którym wynikiem natychmiastowego wywołania jest prawa strona wyrażenia przypisania:

var someVar = (function () {

  // ...

}());

Choć peryferyjne nawiasy są składniowo niepotrzebne, nawiasem otwierającym daje wskazanie up-front, że wartość jest przyporządkowana jest nie sama funkcja, ale raczej wynikiem funkcji jest wywoływany.

Jest to podobne do rady Crockforda dotyczącej kapitalizacji funkcji konstruktora - ma służyć jako wizualna wskazówka dla każdego, kto patrzy na kod źródłowy.

Bobby Eickhoff
źródło
Dziękuję za zwrócenie uwagi. Nigdy nie znalazłem sposobu, jak pozbyć się komunikatu ostrzegawczego JSLint „Zachowaj ostrożność podczas tworzenia funkcji w pętli”. Byłem ostrożny i zamknąłem tę funkcję, ale JSLint nadal narzekał. Teraz wiem, że przyjąłem, że użyłem drugiego wzoru.
viam0Zah
Przez cały ten czas robiłem to „źle”. A kiedy mówię „przez cały ten czas”, piszę JavaScript od 1995 roku.
Dave Land

Odpowiedzi:

73

Z przewodnika po konwencjach stylu Douglassa Crockforda : (wyszukaj „wywołane natychmiast”)

Gdy funkcja ma zostać wywołana natychmiast, całe wyrażenie wywołania powinno być opakowane w pareny, aby było jasne, że tworzona wartość jest wynikiem funkcji, a nie samej funkcji.

Zasadniczo uważa więc, że wyjaśnia to rozróżnienie między wartościami funkcji a wartościami funkcji. Jest to więc kwestia stylistyczna, a nie istotna różnica w samym kodzie.

zaktualizowane odniesienie, stary plik PPT już nie istnieje

cgp
źródło
1
Cieszę się, że to przeczytałem. Właśnie skończyłem czytać Javascript: The Good Parts i ciągle myślałem, że przypisywanie wyniku wywołania funkcji jest naprawdę złą składnią, ponieważ musisz spojrzeć na pierwszą i ostatnią linię, aby zrozumieć, co się dzieje. Nie używa parens do pakowania w książce, ale dokładnie rozumiem, dlaczego je poleca.
Skilldrick
2
@altCognito, czy możesz podać nowy link do PPT?
th1rdey3
1
Przeszukałem
1
Nie mogłem znaleźć oryginalnego PPT, ale udało mi się znaleźć ten sam punkt, co w jego przewodniku po konwencji javascript.
cgp
archive.org ma to?
John Greene,
2

Natychmiast zwane funkcje anonimowe są opakowane w pareny, ponieważ:

  1. Są to wyrażenia funkcyjne i pozostawienie parenów na zewnątrz spowodowałoby zinterpretowanie ich jako deklaracji funkcji, która jest błędem składniowym.

  2. Wyrażenia funkcyjne nie mogą zaczynać się od słowa function.

  3. Podczas przypisywania wyrażenia funkcyjnego do zmiennej, sama funkcja nie jest zwracana, zwracana jest wartość zwracana funkcji, stąd pareny oceniają, co jest w środku i wytwarzają wartość.gdy funkcja jest wykonywana, a końcowe pareny ..}()powodują natychmiastowe wykonanie funkcji.

Dathan
źródło
Dathan, odpowiadasz na inne pytanie. Masz rację, że nawiasy zamykające są czasami niezbędne pod względem składniowym, aby parser mógł odróżnić wyrażenia funkcyjne od deklaracji funkcji. Ale moje pytanie dotyczy umieszczenia nawiasów wywołania. Twoja trzecia kwestia jest niedokładna; w tym przypadku nawiasy zamykające są zbędne.
Bobby Eickhoff
Odpowiadałem na twój pierwszy przykład, w którym funkcja natychmiastowo nazywana anonimowa nie została przypisana do zmiennej, a zatem nawiasy są syntaktycznie konieczne z dwóch pierwszych powodów. Trzecim powodem było właśnie przywrócenie tego, co nawet powiedziałeś: „nawias otwierający wskazuje z góry, że przypisywana wartość nie jest samą funkcją, ale raczej wynikiem wywoływanej funkcji”. Ale myślę, że nie było to jasne.
Dathan
-3

Albo użyj:

void function () {
...
} ()
Agamemnus
źródło