javascript function leading bang! składnia

Widziałem teraz tę składnię w kilku bibliotekach i zastanawiam się, jakie są korzyści. (zauważ, że jestem świadomy zamykania i tego, co robi kod, martwię się tylko różnicami składni)

!function(){
  // do stuff
}();

Jako alternatywa dla bardziej powszechnych

(function(){
  // do stuff
})();

Do samodzielnego wywoływania funkcji anonimowych.

Zastanawiam się nad kilkoma rzeczami. Po pierwsze, co pozwala na to, aby najlepszy przykład rzeczywiście działał? Dlaczego huk jest konieczny, aby złożyć to stwierdzenie poprawna składniowo? Powiedziano mi również, że + działa, i jestem pewien, że niektóre inne, w miejsce ! Po drugie, jaka jest korzyść? Wszystko, co mogę powiedzieć, to to, że oszczędza jedną postać, ale nie wyobrażam sobie, że to tak wielka korzyść, aby przyciągnąć wielu adopterów. Brakuje mi czegoś jeszcze?

Jedyną inną różnicą, jaką widzę, byłaby wartość zwracana funkcji self wywołującej, ale w obu tych przykładach, tak naprawdę nie dbamy o wartość zwracaną funkcja, ponieważ jest używana tylko do tworzenia zamknięcia. Może mi ktoś powiedzieć dlaczego można użyć pierwszej składni?

Author: brad, 2011-04-29

6 answers

Najlepiej, abyś mógł to wszystko zrobić po prostu jako:

function(){
  // do stuff
}(); 

Oznacza to zadeklarowanie funkcji anonimowej i jej wykonanie. Ale to nie zadziała ze względu na specyfikę gramatyki JS.

Więc najkrótszą formą osiągnięcia tego jest użycie jakiegoś wyrażenia np. UnaryExpression (a więc CallExpression):

!function(){
  // do stuff
}(); 

Lub dla Zabawy:

-function(){
  // do stuff
}(); 

Lub:

+function(){
  // do stuff
}(); 

Lub nawet:

~function(){
  // do stuff
  return 0;
}( );
 91
Author: c-smile,
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
2014-08-30 07:27:30

W Javascript oczekuje się, że linia rozpoczynająca się od function będzie funkcją instrukcją i ma wyglądać jak

function doSomething() {
}

Funkcja samo wywołująca jak

function(){
  // do stuff
}();

Nie pasuje do tej formy (i spowoduje błąd składni przy pierwszym otwarciu paren, ponieważ nie ma nazwy funkcji), więc nawiasy są używane do określenia anonimowej funkcji wyrażenie.

(function(){
  // do stuff
})();

Ale wszystko, co tworzy wyrażenie (w przeciwieństwie do instrukcji funkcji) zrobi, stąd !. Mówi interpreterowi, że nie jest to deklaracja funkcji. Poza tym, pierwszeństwo operatora nakazuje, że funkcja jest wywoływana przed negacją.

Nie byłem świadomy tej konwencji, ale jeśli stanie się powszechna, może przyczynić się do czytelności. Chodzi mi o to, że każdy, kto czyta !function na szczycie dużego bloku kodu, będzie oczekiwać samo-inwokacji, tak jak jesteśmy już uwarunkowani, aby oczekiwać tego samego, kiedy widzimy (function. Poza tym, że my straci te irytujące nawiasy. Spodziewałbym się, że to jest powód, w przeciwieństwie do wszelkich oszczędności w szybkości lub liczby postaci.

 71
Author: brainjam,
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-05-21 19:56:17

Poza rzeczami, które zostały już powiedziane, składnia z ! jest przydatne, jeśli piszesz javascript bez średników:

var i = 1
!function(){
  console.log('ham')
}()

i = 2
(function(){
  console.log('cheese')
})()

Pierwszy przykład wyświetla' ham ' zgodnie z oczekiwaniami, ale drugi spowoduje błąd, ponieważ instrukcja i = 2 nie zostanie zakończona z powodu następującego nawiasu.

Również w skonkatenowanych plikach javascript nie musisz się martwić, jeśli w poprzednim kodzie brakuje średników. Więc nie ma potrzeby wspólnego; (function () {}) (); aby upewnić się, że własne nie przerwa.

Wiem, że moja odpowiedź jest trochę spóźniona, ale chyba jeszcze o niej nie wspomniano:)

 43
Author: Smoe,
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-05-26 21:56:57

Po pierwsze, jsPerf pokazuje, że używanie ! (UnaryExpression ' S) jest zwykle szybsze. Czasami wychodzą, żeby być równi, ale kiedy nie są, nie widziałem jeszczenie walniętych o jeden triumf nad innymi jeszcze: http://jsperf.com/bang-function

To zostało przetestowane na najnowszym Ubuntu z najstarszą (per say..) Chrome, Wersja 8. Tak więc wyniki mogą się oczywiście różnić.

Edit: A może coś szalonego jak delete?

delete function() {
   alert("Hi!"); 
}();

Lub void?

void function() {
   alert("Hi!"); 
}();
 6
Author: Shaz,
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
2011-04-29 03:31:08

Więc, z negate "!"i wszystkie inne operatory jednoargumentowe takie jak+, -,~, delete, void, wiele zostało powiedziane, tak podsumowując:

!function(){
  alert("Hi!");
}(); 

Lub

void function(){
  alert("Hi!");
}();

Lub

delete function(){
  alert("Hi!");
}();

I jeszcze kilka przypadków zoperatorami binarnymi dla Zabawy:)

1 > function() {
   alert("Hi!"); 
}();

Lub

1 * function() {
   alert("Hi!"); 
}();

Lub

1 >>> function() {
   alert("Hi!"); 
}();

Lub nawet

1 == function() {
   alert("Hi!"); 
}();

Zostawić ternary dla kogoś innego:)

 3
Author: Arman McHitarian,
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-05-23 12:10:36

Jak widać tutaj, najlepszym sposobem na samodzielne wywołanie metod w javascript jest użycie:

(function(){}()); -> 76,827,475 ops/sec

!function(){}();  -> 69,699,155 ops/sec

(function(){})(); -> 69,564,370 ops/sec
 3
Author: Daniel Sanchez,
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-01-20 11:46:20