Co robi wykrzyknik przed funkcją?

!function () {}();
Author: Sebastian Otto, 2010-09-20

8 answers

Składnia JavaScript 101. Oto deklaracja funkcji :

function foo() {}

Zauważ, że nie ma średnika: jest to tylko funkcja deklaracja. Do uruchomienia funkcji potrzebne jest wywołanie foo().

Teraz, gdy dodamy pozornie nieszkodliwy wykrzyknik: !function foo() {} zamienia go w wyrażenie . Jest to teraz wyrażenie funkcji .

Sama ! nie wywołuje oczywiście funkcji, ale możemy teraz umieścić {[5] } na końcu: !function foo() {}(), który ma wyższy priorytet niż ! i natychmiast wywołuje funkcję.

Więc to, co robi Autor, to zapisywanie bajtów na wyrażenie funkcji; bardziej czytelny sposób zapisu byłby taki:

(function(){})();

Wreszcie, ! sprawia, że wyrażenie zwraca true. Dzieje się tak dlatego, że domyślnie wszystkie bezpośrednio wywołane wyrażenia funkcyjne (IIFE) zwracają undefined, co pozostawia nam !undefined, czyli true. Niezbyt przydatne.

 2215
Author: Neil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-20 21:55:55

Funkcja:

function () {}

Nie zwraca nic (lub niezdefiniowanego).

Czasami chcemy wywołać funkcję poprawnie, gdy ją tworzymy. Możesz się pokusić o wypróbowanie tego:

function () {}()

Ale daje to SyntaxError.

Użycie operatora ! przed funkcją powoduje, że jest ona traktowana jako wyrażenie, więc możemy ją nazwać:

!function () {}()

Zwróci również wartość logiczną odwrotną do wartości zwracanej funkcji, w tym przypadku true, ponieważ !undefined jest true. Jeśli chcesz rzeczywistą wartość zwracaną jako wynik wywołania, spróbuj zrobić to w ten sposób:

(function () {})()
 382
Author: Michael Burr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-02 02:55:22

Jest dobry punkt do użycia ! dla wywołania funkcji oznaczonego na Airbnb JavaScript guide

Ogólnie pomysł na użycie tej techniki na oddzielnych plikach (aka modułach), które później zostają połączone. Zastrzeżenie polega na tym, że pliki powinny być łączone przez narzędzia, które umieszczają nowy plik w nowej linii (co i tak jest powszechnym zachowaniem w większości narzędzi concat). W takim przypadku użycie ! pomoże uniknąć błędu w przypadku pominięcia wcześniej połączonego modułu średnik końcowy, a jednak daje to elastyczność, aby umieścić je w dowolnej kolejności bez obaw.

!function abc(){}();
!function bca(){}();

Będzie działać tak samo jak

!function abc(){}();
(function bca(){})();

Ale zapisuje jeden znak i arbitralnie wygląda lepiej.

I przy okazji każdy z +,-,~,void operatory mają ten sam efekt, jeśli chodzi o wywołanie funkcji, na pewno, jeśli trzeba użyć czegoś, aby powrócić 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 IFE dla jednego separacja kodu jednego modułu i wykorzystanie narzędzia concat do optymalizacji (co sprawia, że jedna linia jednego pliku zadanie), a następnie budowa

!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()

Zrobi 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 podobną pracę, ale tylko w przypadku, gdy nie użyli w pierwszym module. Więc nie są tak bezpieczne, jeśli nie masz całkowitej kontroli nad nakazem konkatenacji.

To działa:

!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()

To nie:

^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
 66
Author: dmi3y,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-19 19:17:14

Zwraca, czy instrukcja może być oceniona na false. eg:

!false      // true
!true       // false
!isValid()  // is not valid

Możesz użyć go dwa razy, aby zmusić wartość do boolean:

!!1    // true
!!0    // false
Tak więc, aby bardziej bezpośrednio odpowiedzieć na twoje pytanie:
var myVar = !function(){ return false; }();  // myVar contains true

Edit: efekt uboczny zmiany deklaracji funkcji na wyrażenie funkcji. Np. poniższy kod nie jest poprawny, ponieważ jest interpretowany jako deklaracja funkcji, której brakuje wymaganego identyfikatora (lub funkcji nazwa):

function () { return false; }();  // syntax error
 29
Author: gilly3,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-07 12:47:17

Jego po prostu zapisać bajt danych, gdy robimy minifikację javascript.

Rozważmy poniższą funkcję anonimową

function (){}

Aby powyższe wywołanie było funkcją self wywołującą, zasadniczo zmienimy powyższy kod jako

(function (){}())

Teraz dodaliśmy dwa dodatkowe znaki (,) oprócz dodania () na końcu funkcji, która jest niezbędna do wywołania funkcji. W procesie minifikacji zazwyczaj skupiamy się na zmniejszeniu rozmiaru pliku. Możemy więc również napisać powyższe function as

!function (){}()

Obie funkcje są samo wywołującymi się funkcjami i zapisujemy również bajt. Zamiast 2 znaków (,) użyliśmy tylko jednego znaku !

 12
Author: Varatharaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-13 18:20:24

Wykrzyknik sprawia, że każda funkcja zawsze zwraca wartość logiczną.
Wartość końcowa jest negacją wartości zwracanej przez funkcję.

!function bool() { return false; }() // true
!function bool() { return true; }() // false

Pominięcie ! w powyższych przykładach byłobySyntaxError .

function bool() { return true; }() // SyntaxError
Jednak lepszym sposobem na osiągnięcie tego celu byłoby:]}
(function bool() { return true; })() // true
 7
Author: oozzal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-19 11:15:29

! jest operatorem logicznym , a nie, jest operatorem boolowskim, który odwróci coś do swojego przeciwieństwa.

Chociaż można ominąć nawiasy wywołanej funkcji za pomocą BANG (!) przed funkcją, nadal będzie odwracać zwrot, który może nie być tym, czego chciałeś. Podobnie jak w przypadku IEFE, zwraca undefined, która po odwróceniu staje się wartością logiczną true.

Zamiast tego użyj nawiasu zamykającego i BANG (!) w razie potrzeby.

// 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

Inne działające operatory...

+(function(){ return false; }());
=> 0

-(function(){ return false; }());
=> -0

~(function(){ return false; }());
=> -1

Operatory Połączone...

+!(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
 5
Author: SoEzPz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-24 15:47:17

To inny sposób zapisu IIFE (natychmiastowo wywoływane wyrażenie funkcji).

Jego inny sposób pisania-

(function( args ) {})()

Tak samo jak

!function ( args ) {}();
 3
Author: kamal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-06 09:56:36