Per capire questo, penso che sia utile lavorare con un esempio più semplice. Dai un'occhiata alle due funzioni memorizzate qui sotto. L'unica differenza è ()
dopo il add : function(){ ... }()
sul codice di memorizzazione riuscito.
var failed_memoization = {
add : function(){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
} //NOTE: NO function call brackets here
}
}
var successful_memoization = {
add : function(){
var counter;
return function(number){
if(counter){
counter = counter + number;
return counter;
}
counter = number;
return counter;
}
}() //NOTE: the function call brackets here!!
};
}
Ora eseguiamo queste due funzioni.
console.log('Failed Memoization');
console.log(failed_memoization.add(5)); //We wanted 5, but this prints the text of the function instead.... Okay, lets try something else
console.log(failed_memoization.add()(5)); //5
console.log(failed_memoization.add()(10)); //10 (Wanted it to be 5+10 = 15.
console.log('successful_memoization');
console.log(successful_memoization.add(8)); //8
console.log(successful_memoization.add(16)); //24 (This is what we wanted 8 + 16 = 24)
Allora, cosa sta succedendo qui è che per successful_memoization
quando abbiamo messo ()
alla fine della sua add : function(){...}()
. In quanto tale, questa funzione viene eseguita immediatamente alla creazione dell'oggetto statico. A sua volta, l'esecuzione di tale funzione restituisce l'oggetto function (number){...}
a cui corrisponde l'assegnazione: add : function (number){...}
NONadd : function(){}
come inizialmente appare.
Ciò che è anche importante notare è che var counter
è dichiarato all'esternoreturn function(name){}
. Poiché è ancora in uso all'interno di add : function(number){...}
, questa variabile è accessibile all'interno di quella funzione. Per failed_memoization.add()(number)
, utilizza un nuovo counter
ogni volta che eseguiamo quella funzione, perché eseguiamo la prima funzione e quindi la funzione interna su ogni chiamata. Per successful_memoization.add(number)
abbiamo eseguito la funzione esterna al momento dell'inizializzazione, quindi counter
verrà mantenuta per tutte le chiamate successive e non verrà sovrascritta.
fonte
2012-09-08 17:24:58
Vale la pena notare che la tecnica della funzione interna che accede alle variabili sulla funzione outter anche dopo che la funzione outter è ritornata, è conosciuta come 'closure' – 7hi4g0
Questo è dal libro Javascript - Le parti buone e c'è una migliore descrizione del processo lì. –