Che cos'è il costrutto (function () {}) () in JavaScript?


790

Sapevo cosa significava, ma ora sto lottando ...

Fondamentalmente sta dicendo document.onload?

(function () {

})();

20
a proposito, anche se vedrai le persone chiamare questa funzione "auto-invocante", chiaramente non è vero. Il termine iife ha il vantaggio di precisione.
AakashM,

6
Questo dà una grande spiegazione di questo costrutto. È anche dove il termine "IIFE" ha avuto origine. benalman.com/news/2010/11/…
jeremysawesome


2
Per la denominazione di questo costrutto, dai un'occhiata anche qui . Leggi lo scopo di questo costrutto e una spiegazione tecnica (anche qui ). Per la sintassi, dai un'occhiata al motivo per cui le parentesi sono necessarie e dove dovrebbero andare .
Bergi,

Risposte:


854

È un'espressione di funzione immediatamente invocata , o IIFE in breve. Si esegue immediatamente dopo la sua creazione.

Non ha nulla a che fare con nessun gestore di eventi per eventi (come document.onload).
Considera la parte all'interno della prima coppia di parentesi: .... è un'espressione di funzione regolare. Quindi guarda l'ultima coppia , questa viene normalmente aggiunta a un'espressione per chiamare una funzione; in questo caso, la nostra espressione precedente.(function(){})();(function(){})();

Questo modello viene spesso utilizzato quando si cerca di evitare di inquinare lo spazio dei nomi globale, poiché tutte le variabili utilizzate all'interno di IIFE (come in qualsiasi altra funzione normale ) non sono visibili al di fuori del suo ambito.
Questo è il motivo per cui, forse, hai confuso questa costruzione con un gestore di eventi per window.onload, perché è spesso usato come questo:

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

Correzione suggerita da Guffa :

La funzione viene eseguita subito dopo la sua creazione, non dopo che è stata analizzata. L'intero blocco di script viene analizzato prima di eseguire qualsiasi codice al suo interno. Inoltre, il codice di analisi non significa automaticamente che viene eseguito, se ad esempio IIFE è all'interno di una funzione, non verrà eseguito fino a quando non viene chiamata la funzione.

Aggiornamento Dato che questo è un argomento piuttosto popolare, vale la pena ricordare che IIFE può anche essere scritto con la funzione freccia di ES6 (come Gajus ha sottolineato in un commento ):

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

@ gion_13 qual è la differenza tra la fase di creazione e la fase di analisi?
Akantoword

1
@jlei come la vedo io, il ciclo di vita di un programma js comprende le seguenti fasi: analisi, creazione / compilazione, esecuzione. Sebbene l'implementazione effettiva (e la denominazione :)) possa variare da browser a browser, possiamo determinare queste fasi nel nostro codice facendo attenzione agli errori di analisi, al sollevamento e agli errori di runtime. Personalmente non ho trovato molte risorse su questo perché è di livello troppo basso e non è qualcosa che il programmatore può controllare. È possibile trovare una sorta di spiegazione in questo post SO: stackoverflow.com/a/34562772/491075
gion_13

@sam firat of all, c'è la dichiarazione varianle e la nuova parola chiave. Ciò significa che nel tuo esempio stai istanziando un nuovo oggetto definito dal suo costruttore (espressione di funzione anonima) e viene invocato tramite il nuovo operatore, non chiamando la definizione come nell'esempio IIFE. Sicuramente quella funzione si comporta come una chiusura per i suoi contenuti ma è di gran lunga un caso d'uso diverso.
gion_13,

In che modo questo inquina lo spazio dei nomi globale? foo non è comunque disponibile al di fuori della funzione. function(){ var foo = '5'; }
Pankaj,

1
@Pankaj - Preso da solo, che non è nemmeno JS sintatticamente valido (è un'espressione di funzione ma non in un contesto di espressione, quindi viene trattato come un errore di sintassi).
Quentin,

109

È solo una funzione anonima che viene eseguita subito dopo la sua creazione.

È come se lo avessi assegnato a una variabile e l'hai usato subito, solo senza la variabile:

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

In jQuery esiste un costrutto simile a cui potresti pensare:

$(function(){
});

Questa è la forma abbreviata di vincolare l' readyevento:

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

Ma i due suddetti costrutti non sono IIFE .


83
Gli ultimi due non sono in realtà IIFE, poiché sono invocati quando il DOM è pronto e non immediatamente
svvac,

15
@swordofpain: Sì, è corretto, non sono IIFE.
Guffa,

@swordofpain considerando il secondo frammento; ci sarebbe qualche valore in add () alla fine della funzione trasformandola in un IIFE?
fascia oraria

Il punto e virgola alla fine è necessario?
FrenkyB,

@FrenkyB Non necessario, no, ma incoraggiato (i punti e virgola spesso non sono effettivamente necessari in Javascript, ma è una buona pratica). Ognuna di queste sono dichiarazioni che includono funzioni anonime, anziché essere dichiarazioni di funzioni.
Ledivin,

52

Un'espressione di funzione immediatamente invocata (IIFE) chiama immediatamente una funzione. Questo significa semplicemente che la funzione viene eseguita immediatamente dopo il completamento della definizione.

Altre tre formulazioni comuni:

// 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.');
}();

Se non ci sono requisiti speciali per il suo valore di ritorno, allora possiamo scrivere:

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

In alternativa, può essere:

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

Puoi persino scrivere:

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

4
l'ultimo 31.new'è sintassi non valida
cat

9
Perché ci sono così tanti modi per scrivere la stessa cosa? !! > _ <Non mi piace questa lingua
Awesome_girl,

6
aae il vincitore è;(function(){}());
Roko C. Buljan,

La spiegazione delle preferenze di Crockford è stata molto utile - spiega le differenze che ho visto in natura, ad es. Il jistery tiny-pubsub gist è passato da una versione all'altra (puoi vedere il cambiamento alla fine del file) e non ho potuto ' Capisco perché.
icc97,

1
@Awesome_girl: Non è che ci sono molti modi per scrivere la stessa cosa; è che JS ha un sistema di tipo libero con operatori che possono operare su qualsiasi tipo di valore. Puoi farlo 1 - 1e puoi farlo altrettanto facilmente true - function(){}. È solo una cosa (un operatore di sottrazione infix) ma con operandi diversi, anche senza senso.

31

Dichiara una funzione anonima, quindi la chiama:

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

Immagino che "argomenti" siano variabili esterne a cui si fa riferimento come "arg" da utilizzare nel contesto locale all'interno della funzione?
Dalibor,

@Dalibor argumentsè speciale ; la mia ipotesi è il risponditore appena capovolto dove vanno i nomi
cat

29

Ciò significa che esegui immediatamente.

quindi se lo faccio:

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/


Secondo esempio:

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

alert(val); //18

1
Non capisco cosa provi da solo?
Exitos,

1
@Exitos perché restituisce quella funzione. Farò un secondo esempio.
Naftali aka Neal,

molto facile da capire +1
Adiii

24

Tale costrutto è chiamato Espressione di funzione immediatamente invocata (IIFE), il che significa che viene eseguito immediatamente. Pensala come una funzione che viene chiamata automaticamente quando l'interprete raggiunge quella funzione.

Caso d'uso più comune:

Uno dei suoi casi d'uso più comuni è limitare la portata di una variabile creata tramite var. Variabili create tramitevar hanno un ambito limitato a una funzione, quindi questo costrutto (che è un wrapper di funzioni attorno a un determinato codice) farà in modo che il proprio ambito variabile non fuoriesca da quella funzione.

Nel seguente esempio, countnon sarà disponibile al di fuori della funzione immediatamente invocata, ovvero l'ambito di countnon uscirà dalla funzione. Dovresti ottenere un ReferenceError, se provi ad accedervi al di fuori della funzione immediatamente invocata comunque.

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

Alternativa ES6 (consigliata)

In ES6, ora possiamo avere variabili create tramite lete const. Entrambi sono a ambito di blocco (a differenza di quello a scopo di varfunzione).

Pertanto, invece di utilizzare quel complesso costrutto di IIFE per il caso d'uso sopra menzionato, è ora possibile scrivere un codice molto più semplice per assicurarsi che l'ambito di una variabile non fuoriesca dal blocco desiderato.

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

In questo esempio, abbiamo usato letper definire la countvariabile che si countlimita al blocco di codice, che abbiamo creato con le parentesi graffe {...}.

Lo chiamo "prigione riccia".


10
Mi piace la denominazione di Curly Jail . Forse si attaccherà :)
gion_13,

15
(function () {
})();

Questo si chiama IIFE (Espressione di funzione immediatamente richiamata). Uno dei famosi modelli di design JavaScript, è il cuore e l'anima del modello moderno dei moduli. Come suggerisce il nome, viene eseguito immediatamente dopo la sua creazione. Questo modello crea un ambito di esecuzione isolato o privato.

JavaScript prima di ECMAScript 6 utilizzava l'ambito lessicale, quindi IIFE è stato utilizzato per simulare l'ambito del blocco. (Con ECMAScript 6 l'oscillazione a blocchi è possibile con l'introduzione delle parole chiave lete const). Riferimento per problemi con l'ambito lessicale

Simula l'ambito del blocco con IIFE

Il vantaggio dell'utilizzo di prestazioni IIFE della partita è la capacità di passare oggetti globali di uso comune come window, documentecc come argomento riducendo la ricerca portata. (Ricorda che JavaScript cerca le proprietà nell'ambito locale e in cima alla catena fino all'ambito globale). Pertanto, l'accesso agli oggetti globali nell'ambito locale riduce i tempi di ricerca come di seguito.

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

Grazie per aver fornito informazioni utili per comprendere la seconda parentesi in IIFE. Anche per chiarire il vantaggio del tempo di ricerca della variabile globale definendoli in definizione
Arsal

11

No, questo costrutto crea solo un ambito per la denominazione. Se lo spezzi in alcune parti puoi vedere che hai un esterno

(...)();

Questa è una chiamata di funzione. Tra parentesi hai:

function() {}

Questa è una funzione anonima. Tutto ciò che viene dichiarato con var all'interno del costrutto sarà visibile solo all'interno dello stesso costrutto e non inquinerà lo spazio dei nomi globale.


11

Questa è un'espressione di funzione richiamata immediatamente in Javascript:

Per capire IIFE in JS, scomponiamo:

  1. Espressione : qualcosa che restituisce un valore
    Esempio: prova a seguire nella console di Chrome. Queste sono espressioni in JS.
a = 10 
output = 10 
(1+3) 
output = 4
  1. Espressione di funzione :
    Esempio:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

Come funziona l'espressione della funzione:
- Quando il motore JS viene eseguito per la prima volta (contesto di esecuzione - Crea fase), questa funzione (sul lato destro di = sopra) non viene eseguita o memorizzata nella memoria. Alla variabile "greet" viene assegnato un valore "non definito" dal motore JS.
- Durante l'esecuzione (contesto di esecuzione - fase di esecuzione), l'oggetto funtion viene creato al volo ( non è ancora stato eseguito ), viene assegnato alla variabile 'greet' e può essere invocato usando 'greet (' somename ')'.

3. Espressione della funzione immediatamente richiamata:

Esempio:

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

console.log(greeting)  // Namaste Santosh. 

Come funziona IIFE :
- Notare '()' immediatamente dopo la dichiarazione di funzione. Ogni oggetto funtion ha una proprietà 'CODE' attaccata che è richiamabile. E possiamo chiamarlo (o invocarlo) usando le parentesi graffe '()'.
- Quindi qui, durante l'esecuzione (Execution Context - Execute Phase), l'oggetto funzione viene creato e viene eseguito contemporaneamente - Quindi ora, la variabile di saluto, invece di avere l'oggetto funtion, ha il suo valore di ritorno (una stringa)

Caso d'uso tipico di IIFE in JS:

Il seguente modello IIFE è abbastanza comunemente usato.

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • stiamo facendo due cose qui. a) Avvolgendo la nostra espressione di funzione tra parentesi graffe (). Questo dice al parser di sintassi che qualunque cosa sia contenuta in () è un'espressione (espressione di funzione in questo caso) ed è un codice valido.
    b) Stiamo invocando questa funzione allo stesso tempo usando il () alla fine di esso.

Quindi questa funzione viene creata ed eseguita contemporaneamente (IIFE).

Importante custodia per IIFE:

IIFE mantiene il nostro codice sicuro.
- IIFE, essendo una funzione, ha un proprio contesto di esecuzione, il che significa che tutte le variabili create al suo interno sono locali a questa funzione e non sono condivise con il contesto di esecuzione globale.

Supponiamo di avere un altro file JS (test1.js) usato nella mia applicazione insieme a iife.js (vedi sotto).

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

Quindi IIFE ci aiuta a scrivere codice sicuro in cui non ci scontriamo involontariamente con gli oggetti globali.


Se creiamo funzioni all'interno di IIFE come possiamo accedervi in ​​qualche altro file js o jsx, ad esempio nel componente reagire.
rock stone

Anche se non abbiamo usato IIFE, la variabile di saluto non si scontrerà con la variabile di saluto globale. Quindi qual è il vantaggio lì?
Willy David Jr

6

Questa è una funzione anonima auto-invocante .

Dai un'occhiata alla spiegazione di W3Schools di una funzione auto-invocante .

Le espressioni di funzione possono essere "auto-invocanti".

Un'espressione auto-invocante viene invocata (avviata) automaticamente, senza essere chiamata.

Le espressioni di funzione verranno eseguite automaticamente se l'espressione è seguita da ().

Non è possibile auto-invocare una dichiarazione di funzione.


3
(function named(){console.log("Hello");}());<- self-executing chiamato funzione
BRYC

@bryc perché dovresti nominare una funzione che non ha bisogno di un nome.
Ricardo Gonzales,

2
@RicardoGonzales Ricorsione suppongo
bryc il

5

Questa è la funzione anonima auto-invocante. Viene eseguito mentre è definito. Ciò significa che questa funzione è definita e si richiama immediatamente dopo la definizione.

E la spiegazione della sintassi è: la funzione all'interno della prima ()parentesi è la funzione che non ha nome e dalla ();parentesi successiva è possibile capire che viene chiamata nel momento in cui viene definita. E puoi passare qualsiasi argomento in questa seconda ()parentesi che verrà afferrato nella funzione che è nella prima parentesi. Vedi questo esempio:

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

Qui "l'oggetto" che stai passando sarà accessibile all'interno della funzione da "obj", poiché lo stai afferrando nella firma della funzione.


2
Questa domanda ha già una risposta accettata e la tua risposta non aggiunge nulla che non sia già stato coperto dalla risposta accettata. Quindi, non c'era assolutamente bisogno di scrivere questa risposta.
Aadit M Shah,

3
Mi piace leggere risposte multiple, a volte il fraseggio dell'una o dell'altra fa la differenza.

Ho pensato che fosse aggiunto perché mi faceva sapere a cosa serviva quella seconda serie di parentesi. Almeno è stato più chiaro qui che ho visto.
Johnny,

La mia preferita Entrambe le estremità del campione IIFE hanno parametri e la mappatura tra i due è resa chiara.
Stephen W. Wright,

4

Comincia qui:

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

Mettilo in una funzione e non è più globale : il tuo obiettivo principale.

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

Chiama subito la funzione - oops:

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

Utilizzare le parentesi per evitare un errore di sintassi:

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

Puoi lasciare il nome della funzione:

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

Non deve essere più complicato di così.


2
L'errore di sintassi sta parlando delle funzioni delle frecce. A quanto ho capito, è una nuova funzionalità di js, e non esisteva alcuni anni fa, ma l'IIFE lo ha fatto. Quindi, la parentesi probabilmente è stata usata originariamente per evitare un errore di sintassi, ma diverso?
JCarlosR,

Potresti rispondere alla domanda @JCarlos? Come giustamente sottolinea che l'IIFE è arrivato molto prima della funzione freccia, aiuterebbe a capire perché è necessario il wrapping.
Script47

@ Script47 Non ho una risposta alla domanda di JCarlos nel commento. Potresti formulare una nuova domanda e pubblicarla, e sono sicuro che otterrai delle buone risposte.
Jim Flood,

@JCarlos quando eseguo quello che genera l'errore, in realtà ottengo Uncaught SyntaxError: Unexpected token )piuttosto che qualsiasi menzione della funzione freccia. Potresti forse condividere un violino con esso lanciando l'errore della funzione freccia?
Script47

2

Funzione anonima autoeseguente. Viene eseguito non appena viene creato.

Un esempio breve e fittizio in cui questo è utile è:

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);

Quindi, invece di creare un elenco ogni volta, lo crei solo una volta (meno sovraccarico).


1
Come scritto, la tua ricerca ricostruisce l'elenco su ogni invocazione. Per evitare ciò, è necessario (1) creare l'elenco e (2) restituire la funzione di ricerca come chiusura con accesso all'elenco appena creato. Puoi farlo facilmente usando il modulo di auto-invocazione anonimo. Vedi jsfiddle.net/BV4bT .
George,

puoi spiegare ... meno spese generali ... non capisco questa parte
HIRA THAKUR

2
Per overhead si intende qualsiasi lavoro eseguito che non è necessario. Non è necessario popolare un array su ciascuna chiamata di funzione, ecco perché un array nell'esempio è popolato da self-exec. funzione anonima solo per la prima volta. Tuttavia, sembra che io abbia fatto un errore nella mia risposta, vedi il link nel commento di George per un esempio corretto.
usoban,

2

Le funzioni di auto-esecuzione vengono in genere utilizzate per incapsulare il contesto ed evitare collusioni di nomi. Qualsiasi variabile definita all'interno di (function () {..}) () non è globale.

Il codice

var same_name = 1;

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

console.log(same_name);

produce questo output:

2
1

Usando questa sintassi eviti di scontrarti con variabili globali dichiarate altrove nel tuo codice JavaScript.


1
Corretto, l'output sarebbe 2 e quindi 1 perché myVar verrebbe eseguito per primo
Dalibor

1
La tua spiegazione fa bene a spiegare l'ambito della funzione ma non riesce a spiegare perché viene eseguita immediatamente. Assegnarlo a una variabile è autolesionista e può anche essere inteso che può essere eseguito più di una volta. var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); Avrebbe lo stesso risultato.
domenicr,

2

Si chiama IIFE - Espressione di funzione immediatamente richiamata. Ecco un esempio per mostrare la sintassi e l'utilizzo. Viene utilizzato per limitare l'uso delle variabili solo fino alla funzione e non oltre.

(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 (Espressione di funzione immediatamente richiamata) è una funzione che viene eseguita non appena lo script si carica e scompare.

Considera la seguente funzione scritta in un file chiamato iife.js

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

Questo codice sopra verrà eseguito non appena carichi iife.js e stamperà ' Hello Stackoverflow! "sulla console degli strumenti di sviluppo".

Per una spiegazione dettagliata vedere Espressione della funzione immediatamente invocata (IIFE)


1

Un altro caso d'uso è la memoizzazione in cui un oggetto cache non è globale:

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

Un'espressione di funzione immediatamente richiamata (IIFE) è una funzione che viene eseguita non appena viene creata. Non ha alcuna connessione con eventi o esecuzione asincrona. È possibile definire un IIFE come mostrato di seguito:

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

La prima coppia di parentesi function () {...} converte il codice tra parentesi in un'espressione. La seconda coppia di parentesi chiama la funzione risultante dall'espressione.

Un IIFEpuò anche essere descritto come una funzione anonima auto-invocante. Il suo utilizzo più comune è limitare l'ambito di una variabile creata tramite var o incapsulare il contesto per evitare collisioni di nomi.


0

Il motivo per cui vengono utilizzate funzioni anonime che si auto-evocano è che non dovrebbero mai essere chiamate da altri codici poiché "impostano" il codice che si intende chiamare (insieme a dare spazio a funzioni e variabili).

In altre parole, sono come programmi che "creano classi", all'inizio del programma. Dopo che sono stati istanziati (automaticamente), le uniche funzioni disponibili sono quelle restituite dalla funzione anonima. Tuttavia, tutte le altre " le funzioni nascoste sono ancora presenti, insieme a qualsiasi stato (variabili impostate durante la creazione dell'ambito).

Molto bello.


0

Il seguente codice:

(function () {

})();

viene chiamata espressione di funzione immediatamente invocata (IIFE).

Si chiama espressione di funzione perché l' ( yourcode )operatore in Javascript la forza in un'espressione. La differenza tra un'espressione di funzione e una dichiarazione di funzione è la seguente:

// declaration:
function declaredFunction () {}

// expressions:

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

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

Un'espressione è semplicemente un gruppo di codice che può essere valutato su un singolo valore . Nel caso delle espressioni nell'esempio precedente, questo valore era un oggetto a singola funzione .

Dopo che abbiamo un'espressione che restituisce un oggetto funzione, possiamo immediatamente invocare l'oggetto funzione con l' ()operatore. Per esempio:

(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

Perché è utile?

Quando abbiamo a che fare con una base di codice di grandi dimensioni e / o quando importiamo varie librerie, aumenta la possibilità di conflitti di denominazione. Quando stiamo scrivendo alcune parti del nostro codice che è correlato (e quindi utilizza le stesse variabili) all'interno di un IIFE, tutte le variabili e i nomi delle funzioni sono associati alle parentesi delle funzioni dell'IIFE . Ciò riduce le possibilità di conflitti di denominazione e consente di nominarli più negligenti (ad esempio, non è necessario prefissarli).


0

Nella sintassi ES6 (invio per me stesso, mentre continuo ad atterrare su questa pagina alla ricerca di un rapido esempio):

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

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

0

Questa funzione è chiamata funzione auto-invocante. Una funzione auto-invocante (chiamata anche auto-esecuzione) è una funzione senza nome (anonima) che viene invocata (chiamata) immediatamente dopo la sua definizione. Leggi di più qui

Quello che fanno queste funzioni è che quando la funzione è definita, La funzione viene immediatamente chiamata, il che consente di risparmiare tempo e righe di codice aggiuntive (rispetto alla chiamata su una linea separata).

Ecco un esempio:

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



0

È un'espressione di funzione, sta per Immediately Invoked Function Expression (IIFE). IIFE è semplicemente una funzione che viene eseguita subito dopo la sua creazione. Quindi, quando la funzione deve attendere che venga chiamata per essere eseguita, IIFE viene eseguita immediatamente. Costruiamo IIFE con l'esempio. Supponiamo di avere una funzione add che accetta due numeri interi come args e restituisce la somma e consente di rendere la funzione add in un IIFE,

Passaggio 1: definire la funzione

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

Passaggio 2: chiamare la funzione racchiudendo tra parentesi l'intera dichiarazione di funzione

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

Passaggio 3: per richiamare immediatamente la funzione è sufficiente rimuovere il testo "aggiungi" dalla chiamata.

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

Il motivo principale per utilizzare un IFFE è quello di preservare un ambito privato all'interno della tua funzione. All'interno del tuo codice javascript vuoi assicurarti di non sovrascrivere alcuna variabile globale. A volte potresti accidentalmente definire una variabile che sovrascrive una variabile globale. Proviamo con l'esempio. supponiamo di avere un file html chiamato iffe.html e che i codici all'interno del tag body siano-

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

Bene, il codice sopra verrà eseguito senza alcuna domanda, ora supponiamo che tu abbia dichiarato una variabile chiamata documento accidentale o intenzionale.

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

finirai in un SyntaxError : redeclaration di documento di proprietà globale non configurabile.

Ma se il tuo desiderio è di dichiarare un documet con nome variabile, puoi farlo usando 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>

Produzione:

inserisci qui la descrizione dell'immagine

Proviamo con un altro esempio, supponiamo di avere un oggetto calcolatrice come muggito-

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

Bene funziona come un incantesimo, e se riassegnassimo accidentalmente il valore dell'oggetto calcolatrice.

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

Sì, finirai con un TypeError: calcolatore.mul non è una funzione iffe.html

Ma con l'aiuto di IFFE possiamo creare un ambito privato in cui possiamo creare un altro calcolatore di nomi di variabili e usarlo;

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

Produzione: inserisci qui la descrizione dell'immagine


-1

Penso che i 2 set di parentesi lo rendano un po 'confuso ma ho visto un altro utilizzo nell'esempio di Google, hanno usato qualcosa di simile, spero che questo ti aiuterà a capire meglio:

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

quindi se windows.appnon è definito, window.app = {}viene immediatamente eseguito, quindi window.appviene assegnato {}durante la valutazione delle condizioni, quindi il risultato è entrambi appe window.appora diventa {}, quindi l'output della console è:

Object {}
Object {}

-1

Di solito, non invochiamo una funzione immediatamente dopo averla scritta nel programma. In termini estremamente semplici, quando si chiama una funzione subito dopo la sua creazione, si chiama IIFE - un nome di fantasia.


-1

Normalmente, il codice JavaScript ha portata globale nell'applicazione. Quando dichiariamo la variabile globale in essa, c'è la possibilità di utilizzare la stessa variabile duplicata in un'altra area dello sviluppo per qualche altro scopo. A causa di questa duplicazione potrebbe verificarsi un errore. Quindi possiamo evitare queste variabili globali usando l'espressione della funzione che invoca immediatamente, questa espressione si autoesegue. Quando creiamo il nostro codice all'interno di questa espressione IIFE , la variabile globale sarà come ambito locale e variabile locale.

Due modi in cui possiamo creare IIFE

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

O

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

Nello snippet di codice sopra, " var app " è ora una variabile locale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.