2012-05-20 10 views
12

sto ottenendo l'erroreTypeError Uncaught: Non è possibile impostare la proprietà '0' di non definito "

Uncaught TypeError: Cannot set property '0' of undefined

per qualche ragione in questa linea

world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif"; 

perché sta succedendo questo

? grazie per qualsiasi aiuto

var x_world_map_tiles = 100; 
var y_world_map_tiles = 100; 

var world_map_array = new Array(x_world_map_tiles); 
for (i=0; i<=2; i++)//create a two dimensional array so can access the map through x and y coords map_array[0][1] etc. 
{ 
world_map_array[i]=new Array(y_world_map_tiles); 
} 


for (i=0; i<=x_world_map_tiles; i++)//just a test 
{ 
for (z=0; z<=y_world_map_tiles; z++)//just a test 
{ 
world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif"; 
} 
} 
+1

* Perché questo accada * Perché 'world_map_array [i]' 'è undefined' ad un certo punto?. Se una matrice ha una lunghezza, ad esempio, '3', gli indici sono' 0', '1',' 2'. Inoltre, se non hai mai assegnato un valore a un indice, sarà 'indefinito'. –

+0

come risolverei questo? – user1406186

+0

quello che sto cercando di fare è creare una matrice bidimensionale per rappresentare una mappa di piastrelle. per esempio. '[0,0] [1,0] [2,0] [0,1] [1,1] [2,1] [0,2] [1,1] [2,2] ' – user1406186

risposta

26

array in JavaScript hanno capricci dei loro propri che non si può essere in attesa se si proviene da altre lingue. Due quelle importanti per il vostro caso d'uso sono:

  1. Non è possibile dichiarare direttamente multidimensionale array in JavaScript.
  2. C'è un piccolo vantaggio in termini di efficienza (e nessuna sicurezza aggiunta) quando si imposta la dimensione della matrice alla creazione.

A differenza di altri linguaggi, JavaScript non assegnerà un blocco di memoria per l'intero array. (Non sa che tipo di oggetti inserirai in ogni cella, e quindi quanta memoria totale avrà bisogno.) Invece, tutto l'argomento size per Array() fa per te è l'impostazione dell'array length proprietà.

per il generale, caso matrice 2D, suggerirei:

  1. creare l'array "top", per es .:

    var i  // the first-order index in a 
        , j  // the second order index in a 
        , a = [] 
    
  2. elementi di un array di inizializzare, se necessario. Si chiama lazy initialization, e, in questo caso, implica semplicemente il test di a[i] esistente prima di provare a assegnare qualcosa a a[i][j], ad es.:

    if (!a[i]) a[i] = [] 
    

    In inglese la dichiarazione di cui sopra si legge: "Se l'elemento i-esimo è a 'falsy', assegnare un array vuoto per l'elemento i-esimo."

  3. Infine, assegnare il valore effettivo alla matrice multideminsional:

    a[i][j] = 'whatever' 
    

Per il vostro caso, si conoscono i valori prima del tempo, in modo da poter inizializzare ogni elemento in anticipo. (Se non stai ignorando la maggior parte degli elementi, tuttavia, un'implementazione pigro può essere meglio, vedi sotto.)

var x, x_length = 100 
    , y, y_length = 100 
    , map = [] 

// Don't be lazy 
for (x = 0; x < x_length; x++) { 
    map[x] = [] 
    for (y = 0; y < y_length; y++) { 
    map[x][y] = 'grass.gif|ongrass.gif|collision.gif|above.gif' 
    } 
} 

Come alcuni altri hanno detto, un array con 100 elementi ha indici numerati da zero a novantanove, quindi un confronto inferiore è più appropriato qui.


Per riferimento, ecco un'implementazione che utilizza l'inizializzazione pigra. Sono andato con un'interfaccia di funzione invece di accedere direttamente alla matrice; è più lungo e più complesso, ma anche più completo.

Lo schema di inizializzazione che ho usato qui è chiamato immediately invoked function expression. Se non lo hai visto prima, lo è uno dei più utili modelli JavaScript e vale la pena dedicare del tempo per capire.

var map = (function (x_length, y_length, v_default, undefined) { 
    // Unless v_default is overwritten, use ... 
    v_default = v_default || 'grass.gif|ongrass.gif|collision.gif|above.gif' 

    // Private backing array; will contain only values for a[x][y] 
    // that were explicitly set. 
    var a = [] 

    // Private helper function. 
    // - Returns `true` if `x` is between `0` and `x_length - 1` 
    // and `y` is between `0` and `y_length - 1`. 
    // - Returns `false` otherwise. 
    function valid (x, y) { 
    return (x >= 0 
     && x < x_length 
     && y >= 0 
     && y < y_length) 
    } 

    // Private helper function. 
    // - Returns `true` if a[x][y] has been set(). 
    // - Returns `false` otherwise. 
    function exists (x, y) { 
    return !!a[x] && !!a[x][y] 
    } 

    // Private getter 
    // - Returns the value of a[x][y] if it has been set(). 
    // - Returns `undefined` if the point (x,y) is invalid. 
    // - Returns `v_default` otherwise. 
    function get (x, y) { 
    if (!valid(x, y))  return undefined 
    else if (exists(x, y)) return a[x][y] 
    else     return v_default 
    } 

    // Private setter 
    // - Returns the value set on success. 
    // - Returns `undefined` on failure 
    function set (x, y, v) { 
    if (valid(x, y)) { 
     // We're being lazy 
     if (!a[x]) a[x] = [] 
     a[x][y] = v 
     return a[x][y] 
    } 
    return undefined 
    } 

    // Return an interface function. 
    // - Pass the function three arguments, (x, y, v), to set a[x][y] = v 
    // - Pass the function two arguments, (x, y), to get a[x][y] 
    return function (x, y, v) { 
    if (arguments.length > 2) { 
     return set(x, y, v) 
    } else { 
     return get(x, y) 
    } 
    } 
})(100, 100) 

Quando ho eseguito il suddetto in nodo, i seguenti test stampati valori ragionevoli:

// Invalid invocations 
console.log('map()    : %s', map()) 
console.log('map( 0)    : %s', map(0)) 
console.log('map(-1, 0)  : %s', map(-1,0)) 
console.log('map( 0, -1)  : %s', map(0, -1)) 
console.log('map(-1, -1)  : %s', map(-1, -1)) 

// Valid invocations 
console.log('map( 0, 0)  : %s', map(0, 0)) 
console.log('map(99, 99)  : %s', map(99, 99)) 
console.log('map( 1, 1)  : %s', map(1,1)) 
console.log('map( 1, 1, "foo") : %s', map(1,1, 'foo')) 
console.log('map( 1, 1)  : %s', map(1,1)) 
2

for (i=0; i<=2; i++) 

deve essere:

for (i=0; i<=x_world_map_tiles ; i++) 
+2

No, deve essere 'per (i = 0; i

+0

@FelixKling Vedi ''per (i = 0; i <= x_world_map_tiles; i ++) // solo un test'' in basso. – Engineer

+0

Ok, d'accordo, funzionerebbe, ma anche questo è errato;) –

2
var x_world_map_tiles = 100; 
var y_world_map_tiles = 100; 
var world_map_array = new Array(x_world_map_tiles); 
for (i=0; i<=2; i++)//create a two dimensional array 
{ 
    world_map_array[i]=new Array(y_world_map_tiles); 
} 
for (i=0; i<x_world_map_tiles; i++) 
{ 
    for (z=0; z<y_world_map_tiles; z++) 
    { 
     world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif"; 
    } 
} 

Come il vostro array ha una lunghezza di 100, si deve andare da 0 a 99 (< 100) e di non 100 (< =)

0

Si sta alimentando l'espressione un valore per i che non esiste in world_map_array. Quindi credo che x_world_map_titles è> 2.

Penso che è necessario riscrivere i<=2 a i<=x_world_map_titles

Inoltre non è necessario specificare la dimensione della matrice. Vorrei solo usare letterali in questo caso:

var x_world_map_tiles = 100; 
var y_world_map_tiles = 100; 

var world_map_array = []; 
for (i=0; i<=x_world_map_tiles; i++) 
    //create a two dimensional array of 101x101 so can access the map through x and y coords map_array[0][1] etc. { 
    world_map_array[i]=[]; 
} 

for (i=0; i<=x_world_map_tiles; i++)//just a test { 
    for (z=0; z<=y_world_map_tiles; z++)//just a test { 
    world_map_array[i][z]="grass.gif|ongrass.gif|collision.gif|above.gif"; 
    } 
} 
Problemi correlati