2017-08-27 9 views
0

J'ai un objet JSON (bien c'est ce que je pensais avoir défini) et j'essaie d'accéder aux valeurs d'un tableau en son sein. Il est en boucle trois fois ce qui est correct, mais la valeur de img.iName est toujours undefinedJavascript: ne pas comprendre la boucle sur la matrice associative

Qu'est-ce que j'ai mal compris?

<div id="dbgDIV">Debug Div<br></div> 
<script> 
    // imgs as a JSON array 
    var gallery = {"imgs": 
       [ // Height and Width to be added 
        {"iName":"File1.jpg", "tName": "File1_th.jpg","cap":"This is a Caption for File1"}, 
        {"iName":"File2.jpg", "tName": "File2_th.jpg","cap":"This is a Caption for File2"}, 
        {"iName":"File3.jpg", "tName": "File3_th.jpg","cap":"This is a Caption for File3"} 
       ], 
       "imgCount":"3" 
    }; 
    var dbgDIV = document.getElementById("dbgDIV"); 
    for (var img in gallery.imgs) { 
     dbgDIV.innerHTML = dbgDIV.innerHTML + "img=" + img.iName + "<br>"; 
     console.log(img.iName); 
    } 

</script> 
+0

utilisation 'in' » pour la liste d'objets. pour ce tableau, utilisez normal pour la boucle –

+0

Vous trouverez extrêmement utile d'apprendre à utiliser le débogueur JavaScript intégré à tous les navigateurs. En effectuant un seul pas dans votre boucle, vous découvrirez immédiatement que 'img' dans la boucle n'était pas une référence à un élément de tableau comme vous le pensiez, mais plutôt un index _array_, c'est-à-dire' 0', '1', ou' 2 '. Prenez le temps d'apprendre à utiliser les outils de développement et le débogueur JavaScript; vous le trouverez très utile. Voici un [guide des Chrome DevTools] (https://developer.chrome.com/devtools). –

+0

Notez également que JavaScript et JSON n'ont pas de "tableaux associatifs". Ils ont des objets, et ils ont des escargots. 'gallery.imgs' est un tableau, et comme les différentes réponses le soulignent, vous ne devriez pas utiliser une boucle' for'..'in' sur un tableau. Mais l'utilisation de 'for'..'in' n'était pas le problème réel ici! La vraie raison pour ne pas utiliser 'for'..'in' sur un tableau est que si' Array.prototype' avait été étendu, ces propriétés supplémentaires apparaîtraient dans votre boucle. Mon commentaire ci-dessus explique la raison réelle du problème. –

Répondre

1

La boucle for...in est le problème. Il suffit d'utiliser une boucle for traditionnelle à l'index dans le tableau:

var gallery = { 
 
    "imgs": [ 
 
    { 
 
     "iName": "File1.jpg", 
 
     "tName": "File1_th.jpg", 
 
     "cap": "This is a Caption for File1" 
 
    }, 
 
    { 
 
     "iName": "File2.jpg", 
 
     "tName": "File2_th.jpg", 
 
     "cap": "This is a Caption for File2" 
 
    }, 
 
    { 
 
     "iName": "File3.jpg", 
 
     "tName": "File3_th.jpg", 
 
     "cap": "This is a Caption for File3" 
 
    } 
 
    ], 
 
    "imgCount": "3" 
 
}; 
 
var dbgDIV = document.getElementById("dbgDIV"); 
 
for (var i = 0; i < gallery.imgs.length; i++) { 
 
    var img = gallery.imgs[i]; 
 
    console.log(img.iName); 
 
}

+0

Je sais que je ne suis pas censé - mais merci beaucoup - lutter pendant plus d'une heure – mcl

+0

vous pouvez également utiliser: pour (laisser img de gallery.imgs) { – fjoe

+0

Bien que je suis d'accord que 'for'..'in ' ne devrait pas être utilisé sur un tableau, ce qui n'était pas la cause du problème d'OP, ni la raison pour laquelle la boucle numérique 'for' le corrigeait (ce n'était pas le cas). Le vrai problème était le changement que vous avez fait en utilisant 'gallery.imgs [i]' (où 'i' est l'index loop/array) au lieu de' img' dans le code d'OP (où OP ne s'est pas rendu compte que 'img' ici était en fait un index de tableau aussi). Et comme d'autres l'ont suggéré, 'for'..'of' ou' .forEach() 'serait une solution plus propre dans les navigateurs modernes. La boucle numérique 'for' serait bonne si vous deviez supporter de très vieux navigateurs. –

1

Le ... dans les boucles itère sur clés, donc dans un tableau itll être

0,1,2 

et ces numéros n'ont pas un iName. Vous pouvez itérer sur valeurs avec la boucle for..of:

for(var img of gallery.imgs) 
1

vous devez utiliser un pour ... de/forEach/boucle au lieu de la boucle for..in vous avez utilisé.

pour démontrer rapidement la différence entre la for..in et la boucle for..of:

Object.prototype.objCustom = function() {}; 
Array.prototype.arrCustom = function() {}; 

let iterable = [3, 5, 7]; 
iterable.foo = 'hello'; 

for (let i in iterable) { 
    console.log(i); // logs 0, 1, 2, "foo", "arrCustom", "objCustom" 
} 
for (let i of iterable) { 
    console.log(i); // logs 3, 5, 7 
} 

qui signifie qu'il ne va pas vraiment à travers les éléments de tableau que vous vouliez, mais les propriétés sur toutes dénombrables du objet. (En javascript toutes les variables sont des objets)

Je vous suggère d'aller avec quelque chose comme:

gallery.imgs.forEach(img => { 
    console.log(img.iName) // "File1.jpg" , "File2.jpg", ... 
});