Comprensione delle chiusure

2

Sto leggendo la guida JavaScript su MDN e provando per capire l'utilità delle chiusure. Questa frase mi ha aiutato di più "In altre parole, le funzioni definite nella chiusura" ricordano "l'ambiente in cui sono state create." E capisco quella parte, ma non capisco perché questa funzione ...

var getCode = (function(){
      var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...

  return function () {
    return secureCode;
  };
})();

getCode();    // Returns the secureCode

è meglio di questa funzione ....

var getCode = (function(){
      var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
      return secureCode;
})();

getCode();    // Returns the secureCode

secureCode dovrebbe essere ancora non modificabile dagli estranei a causa del modo in cui JavaScript definisce l'ambito all'interno delle funzioni.

    
posta ScrollingMarquees 13.05.2016 - 16:19
fonte

4 risposte

1

Nel tuo particolare esempio forzato, non c'è alcuna differenza. Se usi sempre una variabile per valore e assegnagli un valore in fase di compilazione, non importa se usi una chiusura o meno. In effetti, la chiusura potrebbe essere più lenta, a seconda dell'implementazione JavaScript del browser. Questo esempio forzato è semplicemente troppo semplice: non c'è motivo di aver bisogno del potere extra di chiusure.

L'esempio mostrato era di cose che le chiusure possono fare. Nel tentativo di non distrarre dall'intento dell'articolo, l'hanno semplificato eccessivamente a qualcosa che in realtà non mostra affatto la forza di una chiusura.

La mia raccomandazione sarebbe di guardare gli altri esempi sulla pagina. Molti altri, in particolare l'esempio del modello di modulo, mostrano il potere effettivo delle chiusure. L'esempio di modulo non può essere eseguito con variabili locali, mentre l'esempio che hai copiato nella tua domanda potrebbe essere.

    
risposta data 13.05.2016 - 20:47
fonte
5

Non si tratta di un estraneo in grado di cambiarlo. Ecco un esempio migliore che illustra gli utili delle chiusure:

var getCodeForUser = (function(username){
  var secureCode = CalculateCodeFor(username);

  return function () {
    return secureCode;
  };
})("ScrollingMarquees");

getCodeForUser();    // Returns the secureCode

In questo caso la chiusura calcola un valore e quindi genera una funzione che utilizza internamente quel valore generato. La funzione inner ricorda quel valore anche quando lascia quell'ambito con return .

Puoi utilizzare la funzione esterna per generare funzioni per più utenti che poi "ricorderanno" un diverso secureCode .

Ecco un esempio diverso che fa qualcosa di completamente diverso ma illustra l'utilità delle chiusure. Qui abbiamo una funzione che rende gli elementi del pulsante HTML con una funzione di click handler. Si noti che la funzione onclick-handler che genera utilizza una variabile dall'ambito locale che mantiene dopo aver abbandonato l'ambito:

function makeButton(color) {
     var button = document.createElement("button");
     button.style.backgroundColor = color;
     button.innerHTML = color;
     button.onclick = function() {
          alert("I am a " + color + "-colored button");
     }
     return button;
}


var container = document.getElementById("container");

container.appendChild(makeButton("blue"));
container.appendChild(makeButton("red"));
container.appendChild(makeButton("yellow"));
container.appendChild(makeButton("green"));
    
risposta data 13.05.2016 - 16:32
fonte
1

Le persone spesso si entusiasmano parlando di quali chiusure possono fare e dimenticano di parlare di ciò che dovrebbe fare con le chiusure. Il tuo esempio particolare si basa sull'esempio precedente, che mostrava le chiusure che agivano come oggetti di un povero uomo. Questo è lontano dal miglior esempio di uso di chiusura idiomatica, ma è è familiare ai programmatori orientati agli oggetti, che suppongo sia il motivo per cui le persone lo presentano così frequentemente in questi tipi di articoli.

Il tuo esempio continua dove il precedente esempio è stato interrotto, a dimostrazione che non hai nemmeno bisogno di nominare la tua chiusura! È un po 'interessante di curiosità. Ti aiuta a capire come funzionano le chiusure. Potrebbe rivelarsi utile in un contesto diverso, ma così com'è, l'esempio non è molto pratico, e l'autore molto probabilmente non ha intenzione di farlo.

La mia risposta a una domanda correlata precedente mostra un esempio reale di dove le chiusure sono effettivamente migliori delle alternative.

    
risposta data 13.05.2016 - 20:17
fonte
0

Il tuo primo approccio è più vicino al concetto di clousure rispetto al primo.

Tuttavia, quel codice può essere ancora più chiaro

var getCode = function(){ 
      var secureCode = "0]Eal(eh&2"; // A code we do not want outsiders to be able to modify... 
       return secureCode; 
 }; 

getCode(); // Returns the secureCode

Come hai indicato, secureCode non è modificabile.

Ora getCode è un oggetto che può essere passato in funzioni

function method (fnArg){ 
      console.log(fnArg());
}

method(getCode());  //will print a log in browser consolé

Puoi anche collegarlo a un oggetto

var object ={
     method: getCode
};

//invoke getcode
object.method();

O collegalo a un altro oggetto già esistente

var objectA = {};
objectA.method = getCode;

objectA.method();

Nessuno di questi esempi ha accesso a secureCode

Come vedi, questo tipo di funzioni oggetto sono davvero utili.

L'utilizzo principale è usarli come callback nei processi asynch

object.send () onResponse (getCode ());.

o

object. send().onError(function (){
      console.error("KO!");
});

Modifica : Erik ha indicato questi esempi non sono clousure . I clousures hanno lo svantaggio che rende il codice difficile da leggere e molte volte lo scopo di vars potrebbe non essere chiaro.

    
risposta data 13.05.2016 - 16:47
fonte

Leggi altre domande sui tag