Co to jest konstrukcja (function () {}) () w JavaScript?


790

Wcześniej wiedziałem, co to znaczy, ale teraz walczę ...

Czy to w zasadzie mówi document.onload?

(function () {

})();

20
btw, chociaż zobaczysz ludzi nazywających tę funkcję „wywoływaniem siebie”, to oczywiście nie jest prawdą. Termin iife ma tę zaletę, że dokładność.
AakashM

6
To daje świetne wyjaśnienie tego konstruktu. Tam też powstał termin „IIFE”. benalman.com/news/2010/11/…
jeremysawesome


2
Aby zapoznać się z nazwą tego konstruktu, zobacz także tutaj . Przeczytaj o celu tego konstruktu i wyjaśnienie techniczne (również tutaj ). Aby zapoznać się ze składnią, sprawdź, dlaczego nawiasy są potrzebne i dokąd powinny się udać .
Bergi,

Odpowiedzi:


854

Jest to Natychmiast-wywoływana Funkcja Expression lub Iife za krótki. Wykonuje się natychmiast po utworzeniu.

Nie ma to nic wspólnego z żadnym programem obsługi zdarzeń dla jakichkolwiek zdarzeń (takich jak document.onload).
Rozważ część w pierwszej parze nawiasów: .... jest to wyrażenie regularne. Następnie spójrz na ostatnią parę , która zwykle jest dodawana do wyrażenia w celu wywołania funkcji; w tym przypadku nasze wcześniejsze wyrażenie.(function(){})();(function(){})();

Ten wzorzec jest często używany podczas próby uniknięcia zanieczyszczenia globalnej przestrzeni nazw, ponieważ wszystkie zmienne używane w IIFE (jak w każdej innej normalnej funkcji) nie są widoczne poza jego zakresem.
Być może dlatego pomyliłeś tę konstrukcję z modułem obsługi zdarzeń window.onload, ponieważ jest ona często używana w następujący sposób:

(function(){
  // all your code here
  var foo = function() {};
  window.onload = foo;
  // ...
})();
// foo is unreachable here (it’s undefined)

Korekta sugerowana przez Guffę :

Funkcja jest wykonywana zaraz po jej utworzeniu, a nie po przeanalizowaniu. Cały blok skryptu jest analizowany przed wykonaniem kodu. Ponadto parsowanie kodu nie oznacza automatycznie, że jest on wykonywany, jeśli na przykład IIFE znajduje się w funkcji, nie zostanie wykonany, dopóki funkcja nie zostanie wywołana.

Aktualizacja Ponieważ jest to dość popularny temat, warto wspomnieć, że IIFE można również napisać za pomocą funkcji strzałki ES6 (jak Gajus zauważył w komentarzu ):

((foo) => {
 // do something with foo here foo
})('foo value')

@ gion_13 jaka jest różnica między fazą tworzenia a fazą analizy?
akantoword

1
@jlei, tak jak to widzę, cykl życia programu js obejmuje następujące fazy: parsowanie, tworzenie / kompilacja, wykonywanie. Chociaż rzeczywista implementacja (i nazewnictwo :)) może się różnić w zależności od przeglądarki, możemy określić te fazy w naszym kodzie, zwracając uwagę na błędy analizy, podnoszenia i błędów w czasie wykonywania. Osobiście nie znalazłem na ten temat wielu zasobów, ponieważ jest to zbyt niski poziom i nie jest to coś, co programista może kontrolować. Możesz znaleźć wyjaśnienie w tym poście SO: stackoverflow.com/a/34562772/491075
gion_13

@sam firat wszystkich, jest deklaracja varianle i nowe słowo kluczowe. Oznacza to, że w twoim przykładzie tworzysz nowy obiekt zdefiniowany przez jego konstruktor (anonimowe wyrażenie funkcji) i jest on wywoływany przez nowy operator, a nie przez wywołanie zakończenia jak w przykładzie IIFE. Jasne, że ta funkcja działa jak zamknięcie zawartości, ale jest to zdecydowanie inny przypadek użycia.
gion_13

Jak to zanieczyszcza globalną przestrzeń nazw? foo i tak nie jest dostępne poza funkcją. function(){ var foo = '5'; }
Pankaj,

1
@Pankaj - sam w sobie, który nie jest nawet poprawnym składniowo JS (jest wyrażeniem funkcyjnym, ale nie w kontekście wyrażenia, dlatego jest traktowany jako błąd składniowy).
Quentin,

109

To tylko anonimowa funkcja, która jest wykonywana zaraz po jej utworzeniu.

To tak, jakbyś przypisał ją do zmiennej i użył jej zaraz potem, tylko bez tej zmiennej:

var f = function () {
};
f();

W jQuery istnieje podobny konstrukt, o którym możesz myśleć:

$(function(){
});

Oto krótka forma wiązania readywydarzenia:

$(document).ready(function(){
});

Ale powyższe dwa konstrukty nie są IIFE .


83
Dwa ostatnie nie są tak naprawdę IIFE, ponieważ są wywoływane, gdy DOM jest gotowy i nie natychmiast
svvac

15
@swordofpain: Tak, to prawda, nie są to IIFE.
Guffa

@swordofpain, biorąc pod uwagę drugi fragment kodu; czy byłaby jakaś wartość w add () na końcu funkcji przez przekształcenie jej w IIFE?
timebandit

Czy średnik na końcu jest konieczny?
FrenkyB

@FrenkyB Niepotrzebne, nie, ale zachęcane (średniki w JavaScript nie są często konieczne, ale jest to dobra praktyka). Każda z tych instrukcji jest raczej funkcją anonimową niż deklaracją funkcji.
Ledivin,

52

Wywołane natychmiast wyrażenie funkcyjne (IIFE) natychmiast wywołuje funkcję. Oznacza to po prostu, że funkcja jest wykonywana natychmiast po zakończeniu definicji.

Trzy bardziej popularne sformułowania:

// Crockford's preference - parens on the inside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
}());

//The OPs example, parentheses on the outside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
})();

//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
  console.log('Welcome to the Internet. Please follow me.');
}();

Jeśli nie ma specjalnych wymagań dotyczących wartości zwracanej, możemy napisać:

!function(){}();  // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}();  // => NaN

Alternatywnie może to być:

~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();

Możesz nawet napisać:

new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required

4
ostatni 31.new”jest niepoprawną składnią
cat

9
Dlaczego istnieje tak wiele sposobów na napisanie tego samego? !! > _ <Nie podoba mi się ten język
Awesome_girl

6
aa zwycięzcą jest;(function(){}());
Roko C. Buljan

Wyjaśnienie preferencji Crockforda było bardzo użyteczne - wyjaśnia różnice, które widziałem na wolności, np. Gistę jQuery tiny-pubsub zmienił się z jednej wersji na drugą (widać zmianę na końcu pliku) i nie mogłem ' dowiedzieć się, dlaczego.
icc97

1
@Awesome_girl: To nie jest tak, że istnieje wiele sposobów na napisanie tego samego; to dlatego, że JS ma system typu luźnego z operatorami, którzy mogą operować na dowolnym typie wartości. Możesz to zrobić 1 - 1i równie łatwo true - function(){}. To tylko jedna rzecz (operator odejmowania odrostka), ale z różnymi, nawet bezsensownymi operandami.

31

Deklaruje funkcję anonimową, a następnie wywołuje ją:

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);

Sądzę, że „argumenty” to zmienne zewnętrzne, które są określane jako „arg” do użycia w kontekście lokalnym w funkcji?
Dalibor,

@Dalibor argumentsjest wyjątkowy ; zgaduję, że odpowiadający właśnie przerzucił tam, gdzie idą nazwy
kot

29

To znaczy, wykonaj natychmiast.

więc jeśli to zrobię:

var val = (function(){
     var a = 0;  // in the scope of this function
     return function(x){
         a += x;
         return a;
     };
})();

alert(val(10)); //10
alert(val(11)); //21

Fiddle: http://jsfiddle.net/maniator/LqvpQ/


Drugi przykład:

var val = (function(){
     return 13 + 5;
})();

alert(val); //18

1
Nie rozumiem, co świadczy o tym, że sam się powołuje?
Exitos,

1
@Exitos, ponieważ zwraca tę funkcję. Podam drugi przykład.
Naftali alias Neal

bardzo łatwe do zrozumienia +1
Adiii

24

Konstrukt ten nazywa się Wyrażeniem funkcji natychmiast wywołanej (IIFE), co oznacza, że ​​zostanie natychmiast wykonany. Pomyśl o tym jako o funkcji wywoływanej automatycznie, gdy interpreter osiągnie tę funkcję.

Najczęstszy przypadek użycia:

Jednym z najczęstszych przypadków użycia jest ograniczenie zakresu zmiennej wykonanej za pośrednictwem var. Zmienne utworzone za pomocą varmają zakres ograniczony do funkcji, więc ta konstrukcja (która jest opakowaniem funkcji wokół określonego kodu) upewni się, że zakres zmiennej nie wycieknie z tej funkcji.

W poniższym przykładzie countnie będzie on dostępny poza natychmiast wywołaną funkcją, tzn. Zakres countnie wycieknie z funkcji. Powinieneś dostać ReferenceError, jeśli spróbujesz uzyskać do niego dostęp poza natychmiastowo wywoływaną funkcją.

(function () { 
    var count = 10;
})();
console.log(count);  // Reference Error: count is not defined

Alternatywa ES6 (zalecana)

W ES6 możemy teraz tworzyć zmienne poprzez leti const. Oba mają zasięg blokowy (w przeciwieństwie do tego, varktóry ma zasięg funkcjonalny).

Dlatego zamiast używać złożonej konstrukcji IIFE w przypadku użycia, o którym wspomniałem powyżej, możesz teraz napisać znacznie prostszy kod, aby upewnić się, że zakres zmiennej nie wycieknie z pożądanego bloku.

{ 
    let count = 10;
}
console.log(count);  // ReferenceError: count is not defined

W tym przykładzie użyliśmy letdefinicji countzmiennej, która countogranicza się do bloku kodu, który utworzyliśmy za pomocą nawiasów klamrowych {...}.

Nazywam to „Curly Jail”.


10
Lubię nazywać się Curly Jail . Może się uda :)
gion_13

15
(function () {
})();

Nazywa się to IIFE (Natychmiastowe wywołanie funkcji). Jeden ze słynnych wzorców projektowych JavaScript, jest sercem i duszą współczesnego wzoru modułu. Jak sama nazwa wskazuje, wykonuje się natychmiast po utworzeniu. Ten wzorzec tworzy izolowany lub prywatny zakres wykonania.

JavaScript przed ECMAScript 6 używał zakresu leksykalnego, więc IIFE został użyty do symulacji zakresu bloków. (Dzięki zakresowi bloków ECMAScript 6 możliwe jest wprowadzenie słów kluczowych leti const). Odwołanie do problemu z zakresu leksykalnym

Symuluj zakres bloków za pomocą IIFE

Korzyść wydajność wykorzystania Iife jest możliwość, aby przejść powszechnie używanych przedmiotów, takich jak globalne window, documentitd jako argument przez zmniejszenie odnośnika zakresu. (Pamiętaj, że JavaScript szuka właściwości w zasięgu lokalnym i w górę łańcucha aż do zasięgu globalnego). Dostęp do obiektów globalnych w zasięgu lokalnym skraca czas wyszukiwania, jak poniżej.

(function (globalObj) {
//Access the globalObj
})(window);

Dziękujemy za przekazanie informacji umożliwiającej zrozumienie drugiego nawiasu w IIFE. Również dla wyjaśnienia korzyści związanych ze zmienną globalną w czasie wyszukiwania poprzez zdefiniowanie ich w definicji
Arsal

11

Nie, ta konstrukcja tworzy po prostu zakres nazewnictwa. Jeśli rozbijesz go na części, zobaczysz, że masz zewnętrzny

(...)();

To jest wywołanie funkcji. W nawiasie masz:

function() {}

To anonimowa funkcja. Wszystko, co jest zadeklarowane za pomocą var w konstrukcie, będzie widoczne tylko w tym samym konstrukcie i nie zanieczyści globalnej przestrzeni nazw.


11

Jest to wyrażenie funkcji natychmiast wywołane w JavaScript:

Aby zrozumieć IIFE w JS, podzielmy to:

  1. Wyrażenie : Coś, co zwraca wartość
    Przykład: Wypróbuj poniższe w konsoli Chrome. Są to wyrażenia w JS.
a = 10 
output = 10 
(1+3) 
output = 4
  1. Wyrażenie funkcji :
    Przykład:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

Jak działa wyrażenie funkcji:
- Gdy silnik JS uruchamia się po raz pierwszy (Kontekst wykonania - Utwórz fazę), ta funkcja (po prawej stronie = powyżej) nie zostanie wykonana ani zapisana w pamięci. Zmienna „witaj” ma przypisaną „niezdefiniowaną” wartość przez silnik JS.
- Podczas wykonywania (kontekst wykonania - faza wykonania) obiekt funkcji jest tworzony w locie ( jeszcze nie wykonany ), zostaje przypisany do zmiennej „witaj” i można go wywoływać za pomocą polecenia „witaj” („nazwa”).

3. Natychmiast wywołane wyrażenie Funtion:

Przykład:

// IIFE
var greeting = function(name) {
    return 'Namaste' + ' ' + name;
}('Santosh')

console.log(greeting)  // Namaste Santosh. 

Jak działa IIFE :
- Zauważ „()” natychmiast po deklaracji funkcji. Do każdego obiektu funkcji dołączona jest właściwość „CODE”, którą można wywołać. Możemy to nazwać (lub wywołać) za pomocą nawiasów klamrowych „()”.
- Więc tutaj, podczas wykonywania (kontekst wykonania - faza wykonania), obiekt funkcji jest tworzony i wykonywany w tym samym czasie - Więc teraz zmienna powitalna, zamiast mieć obiekt funkcji, ma wartość zwracaną (ciąg znaków)

Typowy przypadek użycia IIFE w JS:

Następujący wzór IIFE jest dość powszechnie stosowany.

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • robimy tutaj dwie rzeczy. a) Zawijanie wyrażenia funkcyjnego w nawiasy klamrowe (). Informuje to parser składni, że cokolwiek umieszczone w () jest wyrażeniem (w tym przypadku wyrażeniem funkcyjnym) i poprawnym kodem.
    b) Przywołujemy tę funkcję w tym samym czasie, używając () na jej końcu.

Ta funkcja jest tworzona i wykonywana jednocześnie (IIFE).

Ważna skrzynka dla IIFE:

IIFE dba o bezpieczeństwo naszego kodu.
- IIFE, będąc funkcją, ma własny kontekst wykonania, co oznacza, że ​​wszystkie zmienne utworzone w nim są lokalne dla tej funkcji i nie są współużytkowane z globalnym kontekstem wykonania.

Załóżmy, że mam inny plik JS (test1.js) użyty w mojej aplikacji wraz z iife.js (patrz poniżej).

// test1.js

var greeting = 'Hello';

// iife.js
// Spelling of Function was not correct , result into error
(function (name) { 
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');

console.log(greeting)   // No collision happens here. It prints 'Hello'.

IIFE pomaga nam pisać bezpieczny kod, w którym nie mimowolnie zderzamy się z obiektami globalnymi.


Jeśli tworzymy funkcje wewnątrz IIFE, w jaki sposób możemy uzyskać do nich dostęp w innym pliku js lub jsx, tj. W komponencie React.
kamienna skała,

Mimo że nie użyliśmy IIFE, zmienna powitania nie koliduje z globalną zmienną powitania. Jaka jest więc zaleta?
Willy David Jr

6

To anonimowa funkcja wywołująca siebie .

Sprawdź objaśnienie W3Schools dotyczące funkcji wywoływania samodzielnego .

Wyrażenia funkcyjne mogą być „wywoływane”.

Wyrażenie samo-wywołujące jest wywoływane (uruchamiane) automatycznie, bez wywoływania.

Wyrażenia funkcyjne będą wykonywane automatycznie, jeśli po wyrażeniu następuje ().

Nie można samodzielnie wywołać deklaracji funkcji.


3
(function named(){console.log("Hello");}());<- samodzielnie wykonywana funkcja o nazwie
bryc

@bryc, dlaczego nazwałbyś funkcję, która nie potrzebuje nazwy.
RicardoGonzales,

2
@RicardoGonzales Recursion Chyba
bryc

5

Jest to anonimowa funkcja samo-wywołująca się. Jest wykonywany, dopóki jest zdefiniowany. Co oznacza, że ​​ta funkcja jest zdefiniowana i wywołuje się natychmiast po definicji.

A wyjaśnienie składni jest następujące: funkcja w pierwszym ()nawiasie to funkcja, która nie ma nazwy, a przy następnym ();nawiasie można zrozumieć, że jest wywoływana w momencie jej zdefiniowania. I możesz przekazać dowolny argument w tym drugim ()nawiasie, który zostanie przechwycony w funkcji, która jest w pierwszym nawiasie. Zobacz ten przykład:

(function(obj){
    // Do something with this obj
})(object);

Tutaj przekazywany „obiekt” będzie dostępny w funkcji przez „obj”, ponieważ pobierasz go w podpisie funkcji.


2
To pytanie ma już zaakceptowaną odpowiedź, a twoja odpowiedź nie dodaje niczego, co nie zostało jeszcze objęte zaakceptowaną odpowiedzią. Dlatego absolutnie nie było potrzeby pisać tej odpowiedzi.
Aadit M Shah,

3
Lubię czytać wiele odpowiedzi, czasem frazowanie jednego lub drugiego robi różnicę.

Pomyślałem, że dodał, ponieważ dał mi znać, do czego służy ten drugi zestaw nawiasów. Przynajmniej było tu wyraźniej, co widziałem.
Johnny

Moje ulubione. Oba końce próbki IIFE mają parametry, a odwzorowanie między nimi jest wyraźne.
Stephen W. Wright,

4

Zacznij tutaj:

var b = 'bee';
console.log(b);  // global

Włącz funkcję i nie będzie już globalna - twoim głównym celem.

function a() {
  var b = 'bee';
  console.log(b);
}
a();
console.log(b);  // ReferenceError: b is not defined -- *as desired*

Natychmiast wywołaj funkcję - ups:

function a() {
  var b = 'bee';
  console.log(b);
}();             // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'

Użyj nawiasów, aby uniknąć błędu składniowego:

(function a() {
  var b = 'bee';
  console.log(b);
})(); // OK now

Możesz pominąć nazwę funkcji:

(function () {    // no name required
  var b = 'bee';
  console.log(b);
})();

To nie musi być bardziej skomplikowane.


2
Błąd składniowy mówi o funkcjach strzałek. Jak rozumiem, jest to nowa funkcja js i nie istniała kilka lat temu, ale IIFE tak. Tak więc nawias prawdopodobnie został użyty pierwotnie, aby uniknąć błędu składniowego, ale inaczej?
JCarlosR

Czy mógłbyś odpowiedzieć na pytanie @JCarlos? Jak słusznie zauważa, że ​​IIFE pojawiło się dużo przed funkcją strzałki, pomogłoby to zrozumieć, dlaczego owijanie jest wymagane.
Script47,

@ Script47 Nie mam odpowiedzi na pytanie JCarlosa w komentarzu. Możesz sformułować nowe pytanie i opublikować je, a jestem pewien, że otrzymasz kilka dobrych odpowiedzi.
Jim Flood

@JCarlos, kiedy wykonuję ten, który zgłasza błąd, faktycznie dostaję Uncaught SyntaxError: Unexpected token )raczej niż jakąkolwiek wzmiankę o funkcji strzałki. Czy mógłbyś podzielić się z nią skrzypcami, rzucając błąd funkcji strzałki?
Script47,

2

Samo-wykonująca się funkcja anonimowa. Jest wykonywany, jak tylko zostanie utworzony.

Jednym z krótkich i obojętnych przykładów, w których jest to przydatne, jest:

function prepareList(el){
  var list = (function(){
    var l = []; 
    for(var i = 0; i < 9; i++){
     l.push(i);
    }
    return l;
  })();

  return function (el){
    for(var i = 0, l = list.length; i < l; i++){
      if(list[i] == el) return list[i];
    }
    return null;
  }; 
} 

var search = prepareList();
search(2);
search(3);

Zamiast tworzyć listę za każdym razem, tworzysz ją tylko raz (mniej kosztów ogólnych).


1
Jak napisano, wyszukiwanie przebudowuje listę przy każdym wywołaniu. Aby tego uniknąć, musisz (1) utworzyć listę i (2) zwrócić funkcję wyszukiwania jako zamknięcie z dostępem do właśnie utworzonej listy. Można to łatwo zrobić, korzystając z anonimowego formularza samo-wywołującego. Zobacz jsfiddle.net/BV4bT .
George,

czy możesz wyjaśnić ... mniej narzutów ... nie rozumiem tej części
HIRA THAKUR,

2
Narzut oznacza każdą wykonaną pracę, która nie jest konieczna. Zapełnianie tablicy przy każdym wywołaniu funkcji nie jest konieczne, dlatego tablica w tym przykładzie jest zapełniana przez self-exec. funkcja anonimowa tylko po raz pierwszy. Wygląda jednak na to, że popełniłem błąd w swojej własnej odpowiedzi. Zobacz link w komentarzu George'a, aby znaleźć odpowiedni przykład.
usoban

2

Samoczynne funkcje są zwykle używane do enkapsulacji kontekstu i unikania zmowy nazw. Wszelkie zmienne zdefiniowane w (function () {..}) () nie są globalne.

Kod

var same_name = 1;

var myVar = (function() {
    var same_name = 2;
    console.log(same_name);
})();

console.log(same_name);

tworzy ten wynik:

2
1

Stosując tę ​​składnię, unikniesz kolizji ze zmiennymi globalnymi zadeklarowanymi gdzie indziej w kodzie JavaScript.


1
Prawidłowo, wynik wyniósłby 2, a następnie 1, ponieważ myVar zostałby uruchomiony jako pierwszy
Dalibor

1
Twoje wyjaśnienie dobrze objaśnia zakres funkcji, ale nie wyjaśnia, dlaczego jest wykonywane natychmiast. Przypisanie jej do zmiennej jest samowystarczalne i może również oznaczać, że można ją wykonać więcej niż jeden raz. var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); Miałby ten sam wynik.
domenicr 20.04.16

2

Nazywa się IIFE - Natychmiastowe wywołanie funkcji. Oto przykład pokazujący jego składnię i użycie. Służy do określania zakresu stosowania zmiennych tylko do funkcji, a nie poza nią.

(function () {
  function Question(q,a,c) {
    this.q = q;
    this.a = a;
    this.c = c;
  }

  Question.prototype.displayQuestion = function() {
    console.log(this.q);
    for (var i = 0; i < this.a.length; i++) {
      console.log(i+": "+this.a[i]);
    }
  }

  Question.prototype.checkAnswer = function(ans) {
    if (ans===this.c) {
      console.log("correct");
    } else {
      console.log("incorrect");
    }
  }

  var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
  var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
  var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);

  var questions = [q1, q2, q3];

  var n = Math.floor(Math.random() * questions.length)

  var answer = parseInt(prompt(questions[n].displayQuestion()));
  questions[n].checkAnswer(answer);
})();

1

IIFE (Natychmiastowe wywołanie wyrażenia funkcyjnego) to funkcja, która jest wykonywana, gdy skrypt ładuje się i znika.

Rozważ poniższą funkcję zapisaną w pliku o nazwie iife.js

(function(){
       console.log("Hello Stackoverflow!");
   })();

Powyższy kod zostanie wykonany zaraz po załadowaniu pliku iife.js i wyświetli „ Hello Stackoverflow ! „w konsoli narzędzi programistycznych”.

Aby uzyskać szczegółowe wyjaśnienie, patrz Wyrażenie funkcji natychmiast wywołane (IIFE)


1

Kolejnym przypadkiem użycia jest zapamiętywanie, w którym obiekt pamięci podręcznej nie jest globalny:

var calculate = (function() {
  var cache = {};
  return function(a) {

    if (cache[a]) {
      return cache[a];
    } else {
      // Calculate heavy operation
      cache[a] = heavyOperation(a);
      return cache[a];
    }
  }
})();

0

Wywołane natychmiast wyrażenie funkcyjne (IIFE) to funkcja, która jest wykonywana natychmiast po jej utworzeniu. Nie ma żadnego związku z żadnymi zdarzeniami ani wykonywania asynchronicznego. Możesz zdefiniować IIFE, jak pokazano poniżej:

(function() {
     // all your code here
     // ...
})();

Pierwsza para funkcji nawiasów () {...} konwertuje kod w nawiasach na wyrażenie. Druga para nawiasów wywołuje funkcję wynikającą z wyrażenia.

IIFEMożna również określić jako samodzielnego wywoływania funkcji anonimowej. Jego najczęstszym zastosowaniem jest ograniczenie zakresu zmiennej wykonanej przez var lub enkapsulacja kontekstu, aby uniknąć kolizji nazw.


0

Powodem, dla którego używane są anonimowe funkcje, jest to, że nigdy nie powinny być wywoływane przez inny kod, ponieważ „konfigurują” kod, który JEST przeznaczony do wywołania (wraz z nadaniem zakresu funkcjom i zmiennym).

Innymi słowy, są one jak programy, które „tworzą klasy” na początku programu. Po ich utworzeniu (automatycznie) dostępne są tylko funkcje zwrócone przez funkcję anonimową. Jednak wszystkie pozostałe „ funkcje ukryte są nadal dostępne, wraz z dowolnym stanem (zmienne ustawione podczas tworzenia zakresu).

Bardzo fajny.


0

Poniższy kod:

(function () {

})();

nazywa się natychmiast wywołanym wyrażeniem funkcyjnym (IIFE).

Nazywa się to wyrażeniem funkcyjnym, ponieważ ( yourcode )operator w Javascript wymusza jego wyrażenie. Różnica między wyrażeniem funkcji a deklaracją funkcji jest następująca:

// declaration:
function declaredFunction () {}

// expressions:

// storing function into variable
const expressedFunction = function () {}

// Using () operator, which transforms the function into an expression
(function () {})

Wyrażenie jest po prostu zbiorem kodu, który można ocenić na jedną wartość . W przypadku wyrażeń w powyższym przykładzie ta wartość była pojedynczym obiektem funkcji .

Po uzyskaniu wyrażenia, które ocenia obiekt funkcji, możemy natychmiast wywołać obiekt funkcji za pomocą ()operatora. Na przykład:

(function() {

  const foo = 10;        // all variables inside here are scoped to the function block
  console.log(foo);

})();

console.log(foo);  // referenceError foo is scoped to the IIFE

Dlaczego to jest przydatne?

Kiedy mamy do czynienia z dużą bazą kodu i / lub importujemy różne biblioteki, zwiększa się prawdopodobieństwo konfliktu nazw. Kiedy piszemy pewne części naszego kodu, które są powiązane (i dlatego używają tych samych zmiennych) wewnątrz IIFE, wszystkie zmienne i nazwy funkcji są ograniczone do nawiasów funkcyjnych IIFE . Zmniejsza to szanse na konflikty nazw i pozwala na nazwanie ich bardziej nieostrożnymi (np. Nie trzeba ich poprzedzać).


0

W składni ES6 (publikowanie dla siebie, ponieważ ciągle ląduję na tej stronie w poszukiwaniu szybkiego przykładu):

// simple
const simpleNumber = (() => {
  return true ? 1 : 2
})()

// with param
const isPositiveNumber = ((number) => {
  return number > 0 ? true : false
})(4)

0

Ta funkcja nazywa się funkcją samowywołania. Funkcja samo-wywołująca się (zwana również funkcją samowykonującą się) to funkcja bezimienna (anonimowa), która jest wywoływana (wywoływana) natychmiast po jej zdefiniowaniu.Przeczytaj więcej tutaj

Funkcje te polegają na tym, że gdy funkcja jest zdefiniowana, funkcja jest natychmiast wywoływana, co oszczędza czas i dodatkowe linie kodu (w porównaniu do wywoływania jej na osobnej linii).

Oto przykład:

(function() {
    var x = 5 + 4;
    console.log(x);
})();



0

Jest to wyrażenie funkcyjne, oznacza natychmiastowe wywołanie wyrażenia funkcyjnego (IIFE). IIFE to po prostu funkcja wykonywana zaraz po jej utworzeniu. Zatem jeśli funkcja musi poczekać, aż zostanie wywołana do wykonania, IIFE jest wykonywany natychmiast. Stwórzmy IIFE na przykładzie. Załóżmy, że mamy funkcję add, która przyjmuje dwie liczby całkowite jako argumenty i zwraca sumę, co pozwala przekształcić funkcję add w IIFE,

Krok 1: Zdefiniuj funkcję

function add (a, b){
    return a+b;
}
add(5,5);

Krok 2: Wywołaj funkcję, zawijając całą deklarację funkcji w nawiasach

(function add (a, b){
    return a+b;
})
//add(5,5);

Krok 3: Aby natychmiast wywołać funkcję, wystarczy usunąć tekst „dodaj” z połączenia.

(function add (a, b){
    return a+b;
})(5,5);

Głównym powodem korzystania z IFFE jest zachowanie zakresu prywatnego w ramach funkcji. Wewnątrz kodu javascript chcesz się upewnić, że nie zastępujesz żadnej zmiennej globalnej. Czasami możesz przypadkowo zdefiniować zmienną, która zastępuje zmienną globalną. Spróbujmy na przykładzie. Załóżmy, że mamy plik HTML o nazwie iffe.html, a kody wewnątrz tagu body to-

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

Cóż, powyższy kod zostanie wykonany bez żadnego pytania, teraz załóżmy, że usuniesz zmienną o nazwie dokument przypadkowo lub celowo.

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
        const document = "hi there";
        console.log(document);
    </script> 
</body>

skończysz w SyntaxError : redeclaration of non-configurable global property document.

Ale jeśli chcesz usunąć dokument z nazwą zmiennej, możesz to zrobić za pomocą IFFE.

<body>
    <div id = 'demo'></div>
    <script>
        (function(){
            const document = "hi there";
            this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
            console.log(document);
        })();
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

Wynik:

wprowadź opis zdjęcia tutaj

Spróbujmy na innym przykładzie, załóżmy, że mamy obiekt kalkulatora taki jak poniżej

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
    </script> 
</body>

Cóż, działa jak urok, co jeśli przypadkowo zmienimy wartość obiektu kalkulatora.

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
        calculator = "scientific calculator";
        console.log(calculator.mul(5,5));
    </script> 
</body>

tak, skończy się na TypeError: kalkulator.mul nie jest funkcją iffe.html

Ale za pomocą IFFE możemy stworzyć prywatny zakres, w którym możemy stworzyć inny kalkulator nazwy zmiennej i użyć go;

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        var cal = (function(){
            var calculator = {
                sub:function(a,b){
                    return a-b;
                },
                div:function(a,b){
                    return a/b;
                }
            }
            console.log(this.calculator.mul(5,10));
            console.log(calculator.sub(10,5));
            return calculator;
        })();
        console.log(calculator.add(5,10));
        console.log(cal.div(10,5));
    </script> 
</body>

Wynik: wprowadź opis zdjęcia tutaj


-1

Myślę, że 2 zestawy nawiasów sprawiają, że jest to trochę mylące, ale widziałem inne użycie w przykładzie Google, użyli czegoś podobnego, mam nadzieję, że pomoże to lepiej zrozumieć:

var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);

więc jeśli windows.appnie jest zdefiniowany, to window.app = {}jest natychmiast wykonywany, więc window.appjest przypisywany {}podczas oceny warunku, więc wynik jest zarówno appi window.appteraz {}, więc wyjście konsoli to:

Object {}
Object {}

-1

Zwykle nie wywołujemy funkcji natychmiast po napisaniu jej w programie. Mówiąc najprościej, gdy wywołujesz funkcję zaraz po jej utworzeniu, nazywa się ona IIFE - fantazyjna nazwa.


-1

Zwykle kod JavaScript ma zasięg globalny w aplikacji. Kiedy zadeklarujemy w nim zmienną globalną, istnieje szansa na użycie tej samej zduplikowanej zmiennej w innym obszarze rozwoju w innym celu. Z powodu tego powielania może wystąpić błąd. Możemy więc uniknąć tych zmiennych globalnych poprzez natychmiastowe wywołanie wyrażenia funkcyjnego, to wyrażenie jest samo-wykonującym się wyrażeniem. Kiedy tworzymy nasz kod wewnątrz tego IIFE wyrażeniu zmienna globalna będzie podobna do zasięgu lokalnego i zmiennej lokalnej.

Dwa sposoby na utworzenie IIFE

(function () {
    "use strict";
    var app = angular.module("myModule", []);
}());

LUB

(function () {
    "use strict";
    var app = angular.module("myModule", []);
})();

W powyższym fragmencie kodu „ var app ” jest teraz zmienną lokalną.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.