Bucla foreach JavaScript pe un obiect de tip array asociativ


De ce bucla mea for for-each nu iterează peste obiectul meu asociativ de tip array în JavaScript?

// Defining an array
var array = [];

// Assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// Expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

jQuery each() ar putea fi util: https://api.jquery.com/jQuery.each/

Răspuns #1

Proprietatea .length urmărește doar proprietățile cu indici numerici (chei). Folosiți șiruri pentru chei.

Poți face asta:

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

Pentru a fi în siguranță, este o idee bună în bucle de acest fel să te asiguri că niciuna dintre proprietăți nu este un rezultat neașteptat al moștenirii:

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

edit — probabil că este o idee bună să menționăm acum că funcția Object.keys() este disponibilă în browserele moderne și în Node etc. Acea funcție returnează cheile „proprii” ale unui obiect, sub formă de array:

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

Funcția de callback transmisă către .forEach() este apelată cu fiecare cheie și indicele cheii în array-ul returnat de Object.keys(). De asemenea, i se transmite array-ul prin care funcția iterează, dar acel array nu este cu adevărat util pentru noi; avem nevoie de obiectul original. Acesta poate fi accesat direct prin nume, dar (în opinia mea) este puțin mai plăcut să îl transmitem în mod explicit, ceea ce se face prin transmiterea unui al doilea argument la .forEach() — obiectul original — care va fi legat ca this în interiorul callback-ului. (Tocmai am văzut că acest lucru a fost menționat într-un comentariu mai jos.)

Răspunsul #2

Aceasta este o abordare foarte simplă. Avantajul este că poți obține și cheile:

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

Pentru ES6:

array.forEach(value => {
  console.log(value)
})

Pentru ES6 (dacă vrei valoarea, indexul și chiar array-ul):

array.forEach((value, index, self) => {
  console.log(value, index, self)
})

Răspunsul #3

Dacă Node.js sau browserul suportă Object.entries(), acesta poate îmbunătăți Object.keys() (așa cum se arată în răspunsul lui Pointy).

const h = {
  a: 1,
  b: 2
};

Object.entries(h).forEach(([key, value]) => console.log(value));
// logs 1, 2

În acest exemplu, forEach folosește atribuirea prin destructurare a unui array.