2010-07-27 8 views
6

Ci sono due versioni, presumibilmente quando l'utente clicca il primo link, avviserà "1", e il secondo collegamento, "2", ecc .:Perché una chiusura JavaScript funziona e l'altra no?

Versione 1:

<a href="#" id="link1">click me</a> 
<a href="#" id="link2">click me</a> 
<a href="#" id="link3">click me</a> 
<a href="#" id="link4">click me</a> 
<a href="#" id="link5">click me</a> 

<script type="text/javascript"> 
    for (i = 1; i <= 5; i++) { 
     document.getElementById('link' + i).onclick = (function() { 
      return function() { 
       var n = i; 
       alert(n); 
       return false; 
      } 
     })(); 
    } 
</script> 

Version 2:

<a href="#" id="link1">click me</a> 
<a href="#" id="link2">click me</a> 
<a href="#" id="link3">click me</a> 
<a href="#" id="link4">click me</a> 
<a href="#" id="link5">click me</a> 

<script type="text/javascript"> 
    for (i = 1; i <= 5; i++) { 
     document.getElementById('link' + i).onclick = (function() { 
      var n = i; 
      return function() { 
       alert(n); 
       return false; 
      } 
     })(); 
    } 
</script> 

La versione 1 non funziona. La versione 2 lo farà. Penso di conoscere il motivo per cui, ma vorrei confrontarmi con le spiegazioni delle altre persone sul motivo per cui la versione 1 non funziona.

risposta

4

versione 1 non funziona perché c'è un comune variabile "i" (un globale variabile in questo caso, perché si è dimenticato var) che è condivisa da tutti i "click" funzione di gestione del ciclo crea.

Nella seconda versione, si crea un nuovo ambito lessicale con la funzione piccolo wrapper. Questo dà a ciascun gestore "click" il proprio "io" privato.

3

Nel secondo esempio viene creata una variabile n = i; che rende il valore i nell'ambito della funzione onclick. Mentre al primo la funzione onclick utilizza ancora un valore globale di i

Io suggerirei di questo utilizzo, invece:

for (i = 1; i <= 5; i++) { 
    document.getElementById('link' + i).onclick = (function(i) { 
     return function() { 
     alert(i); 
     return false; 
     } 
    })(i); 
    } 

In questo caso si otterrà lo stesso comportamento in quanto i sarà la variabile locale per la funzione onclick in quanto è un argomento.

0

Prima non funziona perché: i è la parte di ogni chiusura. Dopo 5 iterazioni ora i è 6 a causa dell'operatore di incremento postfisso. Ogni volta che viene richiamato il gestore eventi riceve il valore di i dal suo ambito di chiusura che è sempre 6.

Seconda parte funziona: poiché ogni chiusura esegue una copia di i in n, n è parte di ogni chiusura.

+0

dall'esame della versione 1, non crea una nuova copia di 'i' ogni volta? –

+0

No. Nella versione 1. non sta eseguendo delle copie durante l'iterazione di foreach. Ma fa una copia quando si fa clic. –

Problemi correlati