!function () {}();
javascript
function
Sebastian Otto
źródło
źródło
Odpowiedzi:
JavaScript składnia 101. Oto deklaracja funkcji :
Zauważ, że nie ma średnika: jest to tylko deklaracja funkcji . Aby
foo()
uruchomić tę funkcję, potrzebujesz wywołania .Teraz, kiedy dodamy pozornie nieszkodliwy wykrzyknik:
!function foo() {}
zamienia to w wyraz . To jest teraz wyrażenie funkcyjne .Samo
!
, oczywiście, nie wywołuje funkcji, ale teraz możemy położyć()
na końcu:!function foo() {}()
który ma wyższy priorytet niż!
i natychmiast wywołuje funkcję.Więc autor robi zapisywanie bajtu na wyrażenie funkcji; bardziej czytelnym sposobem pisania byłoby to:
Na koniec
!
sprawia , że wyrażenie zwraca wartość true. To dlatego, że domyślnie wszystkie powrót Iifeundefined
, który pozostawia nam!undefined
co jesttrue
. Niezbyt przydatne.źródło
!
zwraca wartość logiczną, wszyscy o tym wiemy, ale wielką zaletą jest to, że konwertuje ona również deklarację funkcji na wyrażenie funkcji, dzięki czemu funkcja może być natychmiast wywołana bez zawijania jej w nawiasach. Nie jest to oczywiste i wyraźnie intencja kodera.var foo =
łamie dwuznaczność wyrażeń / wyrażeń i możesz po prostu pisaćvar foo = function(bar){}("baz");
itd.Funkcja:
nic nie zwraca (lub nie jest zdefiniowany).
Czasami chcemy wywołać funkcję w trakcie jej tworzenia. Możesz mieć ochotę spróbować tego:
ale powoduje to
SyntaxError
.Użycie
!
operatora przed funkcją powoduje, że jest ona traktowana jako wyrażenie, więc możemy ją nazwać:Zwróci to również wartość logiczną przeciwną do wartości zwracanej przez funkcję, w tym przypadku
true
, ponieważ!undefined
jesttrue
. Jeśli chcesz, aby rzeczywista wartość zwracana była wynikiem połączenia, spróbuj to zrobić w ten sposób:źródło
!
jest przekształcenie deklaracji funkcji w wyrażenie funkcyjne, to wszystko.!function
składniWarto skorzystać
!
z funkcji wywoływania funkcji zaznaczonej w przewodniku JavaScript airbnbGeneralnie pomysł na użycie tej techniki na osobnych plikach (czyli modułach), które później zostają połączone. Zastrzeżenie polega na tym, że pliki powinny być konkatenowane przez narzędzia, które umieszczają nowy plik w nowej linii (co zresztą jest typowe dla większości narzędzi konkat). W takim przypadku użycie
!
pomoże uniknąć błędu w przypadku, gdy poprzednio skonkatenowany moduł nie zaznaczył średnika końcowego, a jednak zapewni elastyczność bez problemu, aby ustawić je w dowolnej kolejności.Będzie działać tak samo jak
ale zapisuje jedną postać i arbitralnie wygląda lepiej.
A przy okazji każdej z
+
,-
,~
,void
operatorzy mają ten sam efekt, jeśli chodzi o wywoływanie funkcji, na pewno, jeśli trzeba użyć czegoś do powrotu z tej funkcji będą działać inaczej.ale jeśli używasz wzorców IIFE dla jednego pliku separacji kodu jednego modułu i używasz narzędzia concat do optymalizacji (co sprawia, że zadanie dla jednego wiersza i jednego pliku), to budowa
Wykona bezpieczne wykonanie kodu, tak samo jak pierwsza próbka kodu.
Ten wyrzuci błąd, ponieważ JavaScript ASI nie będzie w stanie wykonać swojej pracy.
Jedna uwaga dotycząca operatorów jednoargumentowych, wykonaliby oni podobną pracę, ale tylko na wypadek, gdyby nie używali jej w pierwszym module. Nie są więc tak bezpieczne, jeśli nie masz całkowitej kontroli nad porządkiem konkatenacji.
To działa:
To nie:
źródło
Zwraca, czy instrukcja może dać wartość false. na przykład:
Możesz go użyć dwa razy, aby wymusić wartość logiczną:
Aby bardziej bezpośrednio odpowiedzieć na twoje pytanie:
Edycja: Efektem ubocznym jest zmiana deklaracji funkcji na wyrażenie funkcji. Na przykład poniższy kod jest niepoprawny, ponieważ jest interpretowany jako deklaracja funkcji, w której brakuje wymaganego identyfikatora (lub nazwy funkcji ):
źródło
var myVar = !function(){ return false; }()
może pominąć!
podobnevar myVar = function(){ return false; }()
i funkcja wykona się poprawnie, a wartość zwracana pozostanie nietknięta.true
z!0
ifalse
z!1
. Zapisuje 2 lub 3 znaki.Jest to po prostu zapisanie bajtu danych podczas minimalizacji javascript.
rozważ poniższą anonimową funkcję
Aby uczynić powyższą funkcję samo-wywołującą, ogólnie zmienimy powyższy kod jako
Teraz dodaliśmy dwa dodatkowe znaki
(,)
oprócz dodawania()
na końcu funkcji, które są niezbędne do wywołania funkcji. W procesie minimalizacji zwykle skupiamy się na zmniejszeniu rozmiaru pliku. Możemy więc zapisać powyższą funkcję jakoNadal oba są funkcjami samowywołającymi się, a my również oszczędzamy bajt. Zamiast 2 znaków
(,)
użyliśmy tylko jednego znaku!
źródło
! jest logicznym operatorem NOT , to operator logiczny, który odwróci coś na swoje przeciwieństwo.
Chociaż możesz ominąć nawiasy wywoływanej funkcji, używając BANG (!) Przed funkcją, nadal odwróci ona powrót, co może nie być tym, czego chciałeś. Podobnie jak w przypadku IEFE, zwróci wartość niezdefiniowaną , która po odwróceniu stanie się logiczną wartością prawda.
źródło
Wykrzyknik sprawia, że każda funkcja zawsze zwraca wartość logiczną.
Ostateczna wartość jest negacją wartości zwróconej przez funkcję.
Pominięcie
!
w powyższych przykładach będzie składniowy .Jednak lepszym sposobem na osiągnięcie tego byłoby:
źródło
!
zmienia sposób, w jaki środowisko wykonawcze analizuje funkcję. Sprawia, że środowisko wykonawcze traktuje funkcję jako wyrażenie funkcji (a nie deklarację). Robi to, aby umożliwić programistom natychmiastowe wywołanie funkcji przy użyciu()
składni.!
zastosuje się również (tj. negacja) do wyniku wywołania wyrażenia funkcyjnego.Jest to inny sposób pisania IIFE (natychmiast wywoływane wyrażenie funkcyjne).
Inny sposób pisania -
taki sam jak
źródło
(function (args) {...})()
składnię i pozostawienie tej!function
formy narzędziom do minimalizacji i zaciemniania.!
zaneguje (odwrotnie) wszystko, czego oczekujesz w wyniku, tj. jeśli maszkiedy zadzwonisz
boy
, twój wynik będzietrue
, ale w momencie dodania!
kiedy dzwoniszboy
, tj.!boy
twój wynik będziefalse
. Co innymi słowy znaczy NotBoy , ale tym razem jest to po prostu logiczna wynik, albotrue
albofalse
.To samo dzieje się z
!function () {}();
wyrażeniem, tylko uruchomieniefunction () {}();
spowoduje oznaczenie błędu, ale dodanie!
bezpośrednio przedfunction () {}();
wyrażeniem powoduje, że jest odwrotnie niż to,function () {}();
które powinno Cię zwrócićtrue
. Przykład można zobaczyć poniżej:źródło