Dlaczego moja pętla for-each nie iteruje po moim obiekcie tablicy asocjacyjnej 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]);
}
EDYCJA: jQuery each()
może być pomocna: https://api.jquery.com/jQuery.each/
javascript
arrays
foreach
Szymon Toda
źródło
źródło
associative arrays
w JS: jest to zwykły Array lub Object. Nic nie stoi na przeszkodzie, aby dodać właściwości nienumeryczneArray
, ale to nie oznaczaassociative
- w szczególnościlength
właściwość nie zlicza automatycznie tych właściwości.Odpowiedzi:
.length
Właściwość śledzi tylko właściwości z wskaźników liczbowych (elementy). Używasz łańcuchów do kluczy.Możesz to zrobić:
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]); }
Aby być bezpiecznym, dobrze jest w takich pętlach upewnić się, że żadna z właściwości nie jest nieoczekiwanym wynikiem dziedziczenia:
for (var key in arr_jq_TabContents) { if (arr_jq_TabContents.hasOwnProperty(key)) console.log(arr_jq_TabContents[key]); }
edit - prawdopodobnie warto teraz zauważyć, że
Object.keys()
funkcja jest dostępna w nowoczesnych przeglądarkach oraz w Node itp. Ta funkcja zwraca „własne” klucze obiektu w postaci tablicy:Object.keys(arr_jq_TabContents).forEach(function(key, index) { console.log(this[key]); }, arr_jq_TabContents);
Przekazana funkcja zwrotna
.forEach()
jest wywoływana z każdym kluczem i indeksem klucza w tablicy zwracanej przezObject.keys()
. Przekazał również tablicę, przez którą iteruje funkcja, ale ta tablica nie jest dla nas zbyt przydatna; potrzebujemy oryginalnego przedmiotu . Można to uzyskać bezpośrednio poprzez nazwę, ale (moim zdaniem) trochę przyjemniej jest przekazać to jawnie, co jest zrobione przez przekazanie drugiego argumentu do.forEach()
- oryginalnego obiektu - który będzie powiązany jakthis
wewnątrz wywołania zwrotnego. (Właśnie zobaczyłem, że zostało to odnotowane w komentarzu poniżej).źródło
var arr_jq_TabContents = {};
? Mam na myśli {}[]
a{}
? Tylko różne prototypy?Object.keys(arr_jq_TabContents).forEach( function(key) { ... } );
To bardzo proste podejście. Zaletą jest to, że możesz również zdobyć klucze:
for (var key in array) { var value = array[key]; console.log(key, value); }
W przypadku ES6:
array.forEach(value => { console.log(value) })
Dla ES6: (jeśli chcesz mieć wartość, indeks i samą tablicę)
array.forEach((value, index, self) => { console.log(value, index, self) })
źródło
var
w pętlach sugerujących zasięg, który nie istnieje. Stosowaćvar
przed pętlą lublet
w pętli.for
pętli generuje zakres ograniczony do treścifor
pętli. Ale w JavaScript zmienna zadeklarowana przezvar
jest zawsze funkcją globalną, nawet jeśli zapiszesz ją wfor
pętli. Zobacz tutaj: davidwalsh.name/for-and-against-letvar
w Javascript tworzy zmienne w pamięci nawet po zakończeniu pętli.Jest już kilka prostych przykładów, ale po tym, jak sformułowałeś swoje pytanie, zauważyłem, że prawdopodobnie pochodzisz z tła PHP i oczekujesz, że JavaScript będzie działał w ten sam sposób - tak nie jest. PHP
array
bardzo różni się od JavaScriptArray
.W PHP tablica asocjacyjna może zrobić większość tego, co tablica indeksowana numerycznie (
array_*
funkcje działają, możesz tocount()
zrobić itp.) Po prostu tworzysz tablicę i zaczynasz przypisywać do indeksów łańcuchowych zamiast liczbowych.W JavaScript wszystko jest obiektem (z wyjątkiem prymitywów: string, numeric, boolean), a tablice to pewna implementacja, która pozwala mieć indeksy numeryczne. Wszystko popychany do tablicy wpłynie ITS
length
, i można powtórzyć nad zastosowaniem metod Array (map
,forEach
,reduce
,filter
,find
, itd.) Jednakże, ponieważ wszystko jest obiektem, zawsze jesteś wolny, aby po prostu właściwości przypisywać, bo to jest coś zrobić, aby dowolny obiekt. Notacja w nawiasach kwadratowych to po prostu inny sposób uzyskania dostępu do właściwości, więc w twoim przypadku:array['Main'] = 'Main Page';
jest w rzeczywistości równoważne z:
array.Main = 'Main Page';
Z twojego opisu domyślam się, że chcesz mieć „tablicę asocjacyjną”, ale w przypadku JavaScript jest to prosty przypadek użycia obiektu jako tablicy mieszającej. Wiem też, że to przykład, ale unikaj nieistotnych nazw, które opisują tylko typ zmiennej (np.
array
) I nazwę na podstawie tego, co powinna zawierać (nppages
.). Proste obiekty nie mają wielu dobrych bezpośrednich sposobów iteracji, więc często zamieniamy się następnie w tablice, używając najpierwObject
metod (Object.keys
w tym przypadku - jest to równieżentries
ivalues
jest teraz dodawane do niektórych przeglądarek), które możemy zapętlić.// assigning values to corresponding keys const pages = { Main: 'Main page', Guide: 'Guide page', Articles: 'Articles page', Forum: 'Forum board', }; Object.keys(pages).forEach((page) => console.log(page));
źródło
Jeśli obsługiwany jest plik node.js lub przeglądarka
Object.entries()
, można go użyć jako alternatywy dla korzystaniaObject.keys()
( https://stackoverflow.com/a/18804596/225291 ).const h = { a: 1, b: 2 }; Object.entries(h).forEach(([key, value]) => console.log(value)); // logs 1, 2
w tym przykładzie
forEach
używa przypisania niszczącego tablicy.źródło
arr_jq_TabContents[key]
widzi tablicę jako postać z indeksem 0.źródło
Oto prosty sposób użycia tablicy asocjacyjnej jako ogólnego typu obiektu:
Object.prototype.forEach = function(cb){ if(this instanceof Array) return this.forEach(cb); let self = this; Object.getOwnPropertyNames(this).forEach( (k)=>{ cb.call(self, self[k], k); } ); }; Object({a:1,b:2,c:3}).forEach((value, key)=>{ console.log(`key/value pair: ${key}/${value}`); });
źródło
W większości przypadków jest to (zasadniczo) nieprawidłowe:
var array = []; array["Main"] = "Main page";
To tworzy właściwość niebędącą elementem tablicy o nazwie
Main
. Chociaż tablice są obiektami, zwykle nie chcesz tworzyć na nich właściwości niebędących elementami.Jeśli chcesz indeksować do
array
według tych nazw, zwykle używaszMap
zwykłego obiektu lub zwykłego obiektu, a nie tablicy.Z
Map
(ES2015 +), do którego zadzwonię,map
ponieważ jestem kreatywny:let map = new Map(); map.set("Main", "Main page");
następnie iteracyjne go za pomocą iteratorów z jego
values
,keys
lubentries
metodami, na przykład:for (const value of map.values()) { // Here, `value` will be `"Main page"`, etc. }
Używając zwykłego obiektu, który będę twórczo nazwać
obj
:let obj = Object.create(null); // Creates an object with no prototype obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`
którą następnie iteracyjne jego zawartość za pomocą
Object.keys
,Object.values
, lubObject.entries
, na przykład:for (const value of Object.values(proches_X)) { // Here, `value` will be `"Main page"`, etc. }
źródło
var obj = { no: ["no", 32], nt: ["no", 32], nf: ["no", 32, 90] }; count = -1; // which must be static value for (i in obj) { count++; if (obj.hasOwnProperty(i)) { console.log(obj[i][count]) }; };
w tym kodzie użyłem metody nawiasów do wywołania wartości w tablicy, ponieważ zawierała ona tablicę, jednak w skrócie idea, która zmienna i ma klucz własności i pętla nazywana jest obiema wartościami tablicy skojarzonej
metoda idealna, jeśli jesteś zainteresowany, naciśnij lubię
źródło
Możesz to zrobić
var array = []; // assigning values to corresponding keys array[0] = "Main page"; array[1] = "Guide page"; array[2] = "Articles page"; array[3] = "Forum board"; array.forEach(value => { console.log(value) })
źródło