2015-07-08 9 views
15

Mi sto leggendo questo libro e che ha questo codice di esempioPerché manca la parentesi in questa chiamata di funzione anonima?

function getFunction() { 
    var result = []; 
    for (var i = 0; i < 10; i++) { 
     result[i] = function(num) { 
      return function() { 
       console.log("this is " + num); 
      } 
     }(i); 
    }; 

    return result; 
} 

Si sta lavorando male, ma perché non la funzione anonima qui avvolto tra parentesi come questo (function(...))(i);? E in quali casi è possibile omettere la parentesi nella funzione anonima?

+0

Si noti che esistono altri modi per far sì che una funzione sia un'espressione. Ad esempio: '! Function() {}()' o '0/function() {}()' o il mio preferito '-function() {}()' – slebetman

+0

Vedi anche [perché le parentesi sono necessarie] (http : //stackoverflow.com/q/1634268/1048572) in altri luoghi. – Bergi

risposta

17

Poiché la sintassi per le dichiarazioni di funzione e le espressioni di funzione è identica, JS indica quale si sta utilizzando dal codice attorno alla funzione.

Per evitare che si tratti di una dichiarazione di funzione, è necessario utilizzarlo in un'espressione. Avvolgerlo tra parentesi lo farà ma lo farà precedere con uno = (così come un host di altri operatori). Poiché qui c'è un =, le parentesi non sono necessarie.

8

Poiché è utilizzato come secondo operando per l'operatore di assegnazione =, il motore JS può sicuramente considerarlo come un'espressione di funzione.

Quale non è il caso quando si definisce una funzione anonima autonoma: in tal caso è necessario aiutare il motore a trattarlo come un'espressione, non come una dichiarazione.

2

Queste sono espressioni di funzione immediatamente invocate (IIFE). possono essere utilizzati ovunque sia prevista un'espressione. gli esempi sono sul lato destro di un segno di uguale o su entrambi i lati di un operatore di confronto o anche come argomento per un'altra funzione. Dove è necessaria la parentesi è se sono utilizzati dove non è prevista un'espressione. come nel seguente esempio

var a=1; 
(function(b){ 
    a=b; 
})(2); 
console.log(a); 

che emette 2.

Ovunque un'espressione si prevede i seguenti sono equivalenti

function(a){....}(b);

(function(a){....})(b);

(function(a){....}(b));

Le parentesi sono comunque considerate una best practice perché "suggeriscono" che si tratta di una funzione immediatamente richiamata senza dover scorrere verso il basso fino alla fine della funzione.

4

dichiarazione di funzione regolare è simile al seguente:

function FuncName() { doSomething(); } 

Poi si può chiamare questa funzione in questo modo: le funzioni

FuncName(); 

anonimi sono molto simili:

var FuncName = function YouCanEvenPutANameHereAndItWillBeIgnored() { doSomething(); } 

Se la sintassi per le funzioni regolari e le funzioni anonime è identico, allora come fa JS a distinguerle? Deduce cosa intendi dal contesto. Ecco perché questa espressione funzione richiamata all'istante non funziona:

function(s) { console.log(s); } ('abc'); 

Il parser JS lo legge da sinistra.La linea inizia con function, quindi JS indovina è una dichiarazione di funzione regolare e si aspetta che termini con }. C'è comunque ('abc') dopo la funzione, e JS genera un errore.

Per risolvere il problema, è necessario ingannare JS per analizzare tale funzione come funzione anonima. Per farlo devi renderlo parte di un'espressione. Il modo più popolare è questo:

(function(s) { console.log(s); }) ('abc'); 

Ci sono altri modi, però. Sono meno leggibili, ma funzionano anche loro.

(function(s) { console.log(s); } ('abc')); 
+function(s) { console.log(s); } ('abc'); 
-function(s) { console.log(s); } ('abc'); 
1 * function(s) { console.log(s); } ('abc'); 

Nel tuo caso la funzione è già una parte di un'espressione, quindi non c'è bisogno di aggiungere parentesi.

+1

Il motivo per cui la riga che inizia con 'function' è un errore di analisi è perché la funzione non ha nome. 'log (s) di funzione {console.log (s); } (function (s) {console.log (s);} ('abc')) 'dichiara una funzione' log' e quindi registra 'abc'. Avvolgilo tra parentesi e viene eseguito invece di dichiararlo. Anche '!' È spesso usato per fare il codice analizzato come espressione, interagisce bene con l'inserimento automatico del punto e virgola. – Neil