2013-08-26 16 views
5

Almeno è ciò che penso che succede in questo caso:JavaScript setTimeout non può accedere variabile funzione

function MyFunc() { 
    var people = Array({name: 'Alex', age: 25}, {name: 'Ellen', age: 43}); 
    for (var i=0; i<people.length; i++) { 
     setTimeout(function() { ShowIt(people[i].name) }, 1000); // !!! 
    } 
} 

function ShowIt(name) { 
    alert(name); 
} 

ottengo questo errore Uncaught TypeError: Cannot read property 'name' of undefined, così sembra che all'interno della funzione setTimeout ascoltatore la variabile non è people accessibile. Perché e come posso risolverlo?

+0

Questo è un errore molto comune, vedere questa domanda: http://stackoverflow.com/questions/5226285/settimeout-in-a-for-loop-and-pass-i-as-value –

+1

No, significa quel 'persone [i]' non è definito. Se 'people' non era nel campo di applicazione, si otterrebbe qualcosa come" Uncaught ReferenceError: people is not defined ". –

risposta

21

In realtà persone array è ok. Quello che succede è che il tuo io è in realtà 2 e non c'è un terzo elemento nell'array. Ecco perché ottieni questo errore. Ecco la soluzione:

function MyFunc() { 
    var people = Array({name: 'Alex', age: 25}, {name: 'Ellen', age: 43}); 
    for (var i=0; i<people.length; i++) { 
     (function(i) { 
      setTimeout(function() {    
       ShowIt(people[i].name) 
      }, 1000); 
     })(i); 
    } 
} 

function ShowIt(name) { 
    console.log(name); 
} 

MyFunc(); 

Ecco un jsfiddle http://jsfiddle.net/krasimir/XDfLu/2/

La risposta lunga: quando si utilizza setTimeout si passa una funzione ad esso. Questa funzione viene chiamata in futuro e le cose che realizzi vengono eseguite anche in futuro. In quel momento (quello futuro) il tuo i non è più 0 o 1. In realtà è 2 perché il tuo ciclo è terminato. La soluzione fornita utilizza una chiusura aggiuntiva per creare un altro ambito/contesto. E una volta che la funzione passata a setTimeout viene chiamata, cerca una variabile i. Non esiste una cosa del genere nel suo scopo, quindi sale di un livello. E c'è il valore reale di cui abbiamo bisogno.

+0

Cura di spiegare la soluzione? Che cos'è e perché risolve il problema? –

+0

Risposta modificata. (Non sono sicuro di averlo spiegato abbastanza bene). – Krasimir

+0

Quasi. Anche se hai aggiunto una chiamata di funzione, non importa se la funzione è una chiusura o meno. L'unica cosa importante è che la funzione viene eseguita e crea un nuovo ambito attraverso quello. –

Problemi correlati