Strano comportamento in Javascript ottimizzato per … in loop

Sto facendo un gioco Javascript con il tag canvas, e sto usando un ciclo for enhanced per aggiornare le posizioni dei giocatori.

In breve:

var actors = new Array(); var player = new Actor(0, 0, img); actors[0] = player; function update_positions() { //position 1 for(var a in actors) { //position2 a.xpos += a.xvel; a.ypos += a.yvel; } } 

Appena fuori dal ciclo for in posizione 1, posso accedere al valore corretto degli attori [0] .xvel. All’interno del ciclo for in posizione 2, a.xvel non è definito. Qualcuno può spiegarmi cosa sta succedendo?

L’istruzione for...in è pensata per essere utilizzata per iterare sulle proprietà dell’object , osservando il tuo codice sembra che gli actors siano una matrice (stai impostando l’elemento iniziale con l’indice 0 ).

Questa dichiarazione eseguirà anche la ricerca per indicizzazione della catena del prototipo, se è stato esteso il tipo Array.prototype quelle proprietà verranno iterate e anche l’ordine di iterazione non è garantito.

Ti consiglierei di evitare problemi e iterare usando un ciclo normale per:

 for (var i = 0; i < actors.length; i++) { actors[i].xpos += actor.xvel; actors[i].ypos += actor.yvel; } 

Se ho torto, e gli actors non sono una matrice, ti consiglierei di usare il metodo hasOwnProperty , per assicurarti che la proprietà esista nell'object stesso, e non da qualche parte nella catena del prototipo:

 for (var name in object) { if (object.hasOwnProperty(name)) { // } } 

sembra che tu stia cercando di accedere alle proprietà dell’object sul nome, non sul valore qui. l’indice, in questo caso ‘0’, viene assegnato a ‘a’ nel ciclo for / in.

quello che vuoi fare è accedere al valore del membro dell’array, ovvero: attori [a].

prova questo:

 for(var a in actors) { // a=0 the first time around the loop, actor = actors[a]; // same thing as actors[0]; actor.xpos += actor.xvel; actor.ypos += actor.yvel; } 

Il costrutto for (x in y) scorre gli indici di un array, non i suoi membri.

Prova a utilizzare gli actors[a].xpos anziché solo a.xpos .

Vedi qui per maggiori informazioni su JavaScript for-in loop .

Un’altra opzione è usare la libreria di sottolineatura :

 _.each( actors, function(a) { a.xpos += a.xvel; a.ypos += a.yvel; }); 

o se non vuoi usare il carattere di sottolineatura ma comunque stai usando JQuery, allora puoi fare:

 $.each( actors, function(i, a) { a.xpos += a.xvel; a.ypos += a.yvel; }); 

Una buona caratteristica di questo modello funzionale di iterazione è che è ansible utilizzare var per dichiarare le variabili nel ciclo che sono circoscritte al corpo del ciclo, il che aiuta a evitare di essere morsi dalle regole di scope variabile dispari di JavaScript.