!function () {}();
!function () {}();
Odpowiedzi:
JavaScript składnia 101. Oto deklaracja funkcji :
function foo() {}
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:
(function(){})();
Na koniec !
sprawia , że wyrażenie zwraca wartość true. To dlatego, że domyślnie wszystkie powrót Iife undefined
, który pozostawia nam !undefined
co jest true
. Niezbyt przydatne.
!
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:
function () {}
nic nie zwraca (lub nie jest zdefiniowany).
Czasami chcemy wywołać funkcję w trakcie jej tworzenia. Możesz mieć ochotę spróbować tego:
function () {}()
ale powoduje to SyntaxError
.
Użycie !
operatora przed funkcją powoduje, że jest ona traktowana jako wyrażenie, więc możemy ją nazwać:
!function () {}()
Zwróci to również wartość logiczną przeciwną do wartości zwracanej przez funkcję, w tym przypadku true
, ponieważ !undefined
jest true
. Jeśli chcesz, aby rzeczywista wartość zwracana była wynikiem połączenia, spróbuj to zrobić w ten sposób:
(function () {})()
!
jest przekształcenie deklaracji funkcji w wyrażenie funkcyjne, to wszystko.
!function
składni
Warto skorzystać !
z funkcji wywoływania funkcji zaznaczonej w przewodniku JavaScript airbnb
Generalnie 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.
!function abc(){}();
!function bca(){}();
Będzie działać tak samo jak
!function abc(){}();
(function bca(){})();
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.
abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?
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
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
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.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
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:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
To nie:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Zwraca, czy instrukcja może dać wartość false. na przykład:
!false // true
!true // false
!isValid() // is not valid
Możesz go użyć dwa razy, aby wymusić wartość logiczną:
!!1 // true
!!0 // false
Aby bardziej bezpośrednio odpowiedzieć na twoje pytanie:
var myVar = !function(){ return false; }(); // myVar contains true
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 ):
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
może pominąć !
podobne var myVar = function(){ return false; }()
i funkcja wykona się poprawnie, a wartość zwracana pozostanie nietknięta.
true
z !0
i false
z !1
. Zapisuje 2 lub 3 znaki.
Jest to po prostu zapisanie bajtu danych podczas minimalizacji javascript.
rozważ poniższą anonimową funkcję
function (){}
Aby uczynić powyższą funkcję samo-wywołującą, ogólnie zmienimy powyższy kod jako
(function (){}())
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ę jako
!function (){}()
Nadal oba są funkcjami samowywołającymi się, a my również oszczędzamy bajt. Zamiast 2 znaków (,)
użyliśmy tylko jednego znaku!
! 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.
Zamiast tego użyj nawiasu zamykającego i BANG ( ! ), Jeśli to konieczne.
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.
(function(){ return false; }());
=> false
!(function(){ return false; }());
=> true
!!(function(){ return false; }());
=> false
!!!(function(){ return false; }());
=> true
Inni operatorzy, którzy działają ...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Połączeni operatorzy ...
+!(function(){ return false; }());
=> 1
-!(function(){ return false; }());
=> -1
!+(function(){ return false; }());
=> true
!-(function(){ return false; }());
=> true
~!(function(){ return false; }());
=> -2
~!!(function(){ return false; }());
=> -1
+~(function(){ return false; }());
+> -1
Wykrzyknik sprawia, że każda funkcja zawsze zwraca wartość logiczną.
Ostateczna wartość jest negacją wartości zwróconej przez funkcję.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Pominięcie !
w powyższych przykładach będzie składniowy .
function bool() { return true; }() // SyntaxError
Jednak lepszym sposobem na osiągnięcie tego byłoby:
(function bool() { return true; })() // true
!
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 -
(function( args ) {})()
taki sam jak
!function ( args ) {}();
(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 masz
var boy = true;
undefined
boy
true
!boy
false
kiedy zadzwonisz boy
, twój wynik będzie true
, ale w momencie dodania !
kiedy dzwonisz boy
, tj. !boy
twój wynik będzie false
. Co innymi słowy znaczy NotBoy , ale tym razem jest to po prostu logiczna wynik, albo true
albo false
.
To samo dzieje się z !function () {}();
wyrażeniem, tylko uruchomienie function () {}();
spowoduje oznaczenie błędu, ale dodanie !
bezpośrednio przed function () {}();
wyrażeniem powoduje, że jest odwrotnie niż to, function () {}();
które powinno Cię zwrócić true
. Przykład można zobaczyć poniżej:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true