Cum se creează o matrice asociativă în JavaScript. JQuery - Iterare matrice, obiect și elemente definiție și aplicație

  • I. Iterarea asupra matricelor reale
    1. Pentru fiecare și metode conexe
    2. Pentru buclă
    3. Utilizarea corectă a pentru ... în buclă
    4. Pentru ... de buclă (utilizarea implicită a unui iterator)
    5. Utilizarea explicită a unui iterator
    1. Folosind metode pentru a itera peste matrice reale
    2. Conversia într-o matrice reală
    3. O notă despre obiectele de execuție

I. Iterarea asupra matricelor reale

În acest moment, există trei moduri de a itera peste elementele unui tablou real:
  1. array.prototype.forEach fiecare metodă;
  2. clasic pentru bucla;
  3. Un bine format pentru ... în buclă.
În plus, în curând, odată cu apariția noului standard ECMAScript 6 (ES 6), se așteaptă încă două modalități:
  1. pentru ... de buclă (utilizarea implicită a unui iterator);
  2. utilizarea explicită a unui iterator.

1. Metoda forEach și metodele conexe

Dacă proiectul dvs. este conceput pentru a sprijini capabilitățile standardului ECMAScript 5 (ES5), puteți utiliza una dintre inovațiile sale - metoda forEach.

Exemplu de utilizare:
var a \u003d ["a", "b", "c"]; a.forEach (function (entry) (console.log (entry);));
În general, utilizarea forEach necesită conectarea bibliotecii de emulare es5-shim pentru browserele care nu au suport nativ pentru această metodă. Acestea includ IE 8 și versiunile anterioare, care sunt încă în uz astăzi.

Avantajul forEach este că nu este nevoie să declarați variabile locale pentru a stoca indexul și valoarea elementului matrice curent, deoarece acestea sunt transmise automat la funcția de apel invers ca argumente.

Dacă sunteți îngrijorat de costul potențial al apelării unui apel invers pentru fiecare articol, nu vă faceți griji și citiți acest lucru.

ForEach este conceput pentru a itera pe toate elementele unui tablou, dar în afară de acesta ES5 oferă mai multe metode mai utile pentru iterarea pe toate sau unele dintre elemente, plus efectuarea unor acțiuni cu acestea:

  • every - returnează true dacă pentru fiecare element al matricei callback returnează o valoare care este exprimată la true.
  • some - returnează true dacă pentru cel puțin un element al matricei callback returnează o valoare care este exprimată la true.
  • filtru - creează o nouă matrice care conține acele elemente ale matricei originale pentru care returnarea apelului returnează adevărat.
  • hartă - creează o nouă matrice care conține valorile returnate de apelul invers.
  • reduce - reduce o matrice la o singură valoare, aplicând un callback pe rând la fiecare element al matricei, începând cu primul (poate fi util pentru calcularea sumei elementelor matricei și a altor funcții finale).
  • reduceRight - Funcționează similar cu reduce, dar repetă elementele în ordine inversă.

2. Bucla for

Vechi pentru reguli:

Var a \u003d ["a", "b", "c"]; index var; for (index \u003d 0; index< a.length; ++index) { console.log(a); }
Dacă lungimea matricei nu se schimbă pe întreaga buclă, iar bucla în sine aparține unei bucăți de cod critice pentru performanță (ceea ce este puțin probabil), atunci puteți utiliza versiunea „mai optimă” a pentru cu stocarea lungimii matricei:

Var a \u003d ["a", "b", "c"]; var index, len; for (index \u003d 0, len \u003d a.length; index< len; ++index) { console.log(a); }
În teorie, acest cod ar trebui să ruleze puțin mai rapid decât cel anterior.

Dacă ordinea de iterație nu este importantă, atunci puteți merge chiar mai departe în ceea ce privește optimizarea și a scăpa de variabila pentru stocarea lungimii tabloului prin schimbarea ordinii de iterație la opus:

Var a \u003d ["a", "b", "c"]; index var; for (index \u003d a.length - 1; index\u003e \u003d 0; --index) (console.log (a);)
Cu toate acestea, în motoarele JavaScript moderne, aceste jocuri optimizate nu înseamnă de obicei nimic.

3. Utilizarea corectă a buclei pentru ... în buclă

Dacă vi se recomandă să utilizați o buclă pentru ... în buclă, amintiți-vă că iterarea peste tablouri nu este destinată. Contrar concepției greșite obișnuite, bucla for ... in nu se repetă peste indicii matricei, ci proprietățile enumerate ale obiectului.

Cu toate acestea, în unele cazuri, cum ar fi iterarea peste matrice rare, pentru ... in poate fi utilă, atâta timp cât luați unele precauții, așa cum se arată în exemplul de mai jos:

// a este un tablou rar var a \u003d; a \u003d "a"; a \u003d "b"; a \u003d "c"; for (var key in a) (if (a.hasOwnProperty (key) && /^0$|^\\d*$/.test(key) && key<= 4294967294) { console.log(a); } }
În acest exemplu, la fiecare iterație a buclei, se efectuează două verificări:

  1. că matricea are propria proprietate numită cheie (care nu este moștenită de la prototipul său).
  2. acea cheie este un șir care conține notația zecimală a unui număr întreg a cărui valoare este mai mică de 4294967294. De unde vine ultimul număr? Din definiția unui index de matrice în ES5, ceea ce implică faptul că cel mai mare indice pe care îl poate avea un element dintr-o matrice este (2 ^ 32 - 2) \u003d 4294967294.
Desigur, astfel de verificări vor ocupa timp suplimentar la executarea buclei. Dar, în cazul unei matrici rare, această metodă este mai eficientă decât o buclă for, deoarece în acest caz sunt repetate doar acele elemente care sunt definite în mod explicit în matrice. Deci, în exemplul de mai sus, vor fi efectuate doar 3 iterații (pentru indicii 0, 10 și 10000) - versus 10001 în bucla for.

Pentru a nu scrie un cod atât de greoi de verificări de fiecare dată când trebuie să iterați pe o matrice, îl puteți proiecta ca o funcție separată:

Funcție arrayHasOwnIndex (array, key) (return array.hasOwnProperty (key) && /^0$|^\\d*$/.test(key) && key<= 4294967294; }
Apoi corpul buclei din exemplu va fi redus semnificativ:

Pentru (cheie în a) (dacă (arrayHasOwnIndex (a, cheie)) (console.log (a);))
Codul de verificare de mai sus este universal, potrivit pentru toate cazurile. Dar, în schimb, puteți utiliza o versiune mai scurtă, deși în mod formal nu este complet corectă, dar totuși potrivită pentru majoritatea cazurilor:

Pentru (cheie în a) (dacă (a.hasOwnProperty (cheie) && String (parseInt (cheie, 10)) \u003d\u003d\u003d cheie) (console.log (a);))

4. For ... of loop (utilizarea implicită a unui iterator)

ES6, deși este încă în starea de proiect, ar trebui să introducă iteratorii în JavaScript.

Iterator este un protocol implementat prin obiecte care definește un mod standard de a obține o succesiune de valori (finite sau infinite).
Un iterator este un obiect în care este definită metoda next () - o funcție fără argumente care returnează un obiect cu două proprietăți:

  1. done (boolean) - adevărat dacă iteratorul a ajuns la sfârșitul secvenței care este iterată. În caz contrar, fals.
  2. valoare - definește valoarea returnată de iterator. Poate fi nedefinit (absent) dacă proprietatea realizată este adevărată.
Multe obiecte încorporate, incl. matricele reale au iteratori impliciti. Cea mai simplă modalitate de a utiliza un iterator pe tablouri reale este de a folosi noul pentru ... de construct.

Un exemplu de utilizare pentru ... din:

Var val; var a \u003d ["a", "b", "c"]; for (val of a) (console.log (val);)
În exemplul de mai sus, bucla pentru ... of apelează implicit iteratorul obiectului Array pentru a obține fiecare valoare din matrice.

5. Utilizarea explicită a unui iterator

Iteratorii pot fi folosiți în mod explicit, totuși, în acest caz, codul devine mult mai complicat în comparație cu for ... of loop. Arată așa:

Var a \u003d ["a", "b", "c"]; var it \u003d a.entries (); intrare var; while (! (entry \u003d it.next ()). done) (console.log (entry.value);)
În acest exemplu, metoda Array.prototype.entries returnează un iterator care este utilizat pentru a afișa valorile matricei. La fiecare iterație, entry.value conține o matrice precum [cheie, valoare].

II. Iterează peste obiecte asemănătoare matricei

În plus față de matricele reale, JavaScript conține și obiecte asemănătoare matricei ... Ceea ce au în comun cu matricele reale este că au o proprietate de lungime și proprietăți cu nume sub formă de numere care corespund elementelor matricei. Exemplele includ DOM-ul colecției NodeList și argumentele pseudo-matrice disponibile în cadrul oricărei funcții / metode.

1. Utilizarea metodelor de iterație peste matrice reale

Cel puțin majoritatea, dacă nu toate, metodele de iterație peste matrice reale pot fi utilizate pentru a itera peste obiecte asemănătoare matricei.

Pentru și pentru ... în construcții pot fi aplicate obiectelor asemănătoare matricei exact în același mod ca și matricilor reale.

ForEach și alte metode Array.prototype se aplică și obiectelor asemănătoare matricei. Pentru a face acest lucru, utilizați un apel către Function.call sau Function.apply.

De exemplu, dacă doriți să aplicați pentru fiecare la proprietatea childNodes a unui obiect Node, o puteți face astfel:

Array.prototype.forEach.call (node.childNodes, funcție (copil) (// faceți ceva cu obiectul copil));
Pentru ușurința reutilizării acestei tehnici, puteți declara o referință la metoda Array.prototype.forEach într-o variabilă separată și o puteți folosi ca o prescurtare:

// (Aceasta presupune că tot codul de mai jos este în același domeniu) var forEach \u003d Array.prototype.forEach; // ... forEach.call (node.childNodes, function (child) (// face ceva cu obiectul child));
Dacă un obiect asemănător matricei are un iterator, atunci acesta poate fi folosit în mod explicit sau implicit pentru a itera peste obiect în același mod ca și pentru tablourile reale.

2. Convertiți într-o matrice reală

Există, de asemenea, un alt mod foarte simplu de a itera peste un obiect asemănător matricei: convertiți-l într-un tablou real și utilizați oricare dintre metodele de mai sus pentru a itera peste matricele reale. Pentru conversie, puteți utiliza metoda generică Array.prototype.slice, care poate fi aplicată oricărui obiect de tip matrice. Acest lucru se face foarte simplu, așa cum se arată în exemplul de mai jos:

Var trueArray \u003d Array.prototype.slice.call (arrayLikeObject, 0);
De exemplu, dacă doriți să convertiți o colecție NodeList într-o matrice reală, aveți nevoie de cod ca acesta:

Var divs \u003d Array.prototype.slice.call (document.querySelectorAll ("div"), 0);
Actualizați: După cum sa menționat în comentariile rock și torbasow, în ES6 puteți utiliza metoda Array.from mai descriptivă în loc de Array.prototype.slice.

3. O notă privind obiectele de execuție

Dacă aplicați metode Array.prototype obiectelor runtime (cum ar fi colecțiile DOM), atunci ar trebui să aveți în vedere faptul că aceste metode nu sunt garantate să funcționeze corect în toate mediile de runtime (inclusiv browserele). Depinde de comportamentul unui anumit obiect într-un anumit timp de rulare, mai precis, de modul în care operația abstractă HasProperty este implementată în acest obiect. Problema este că standardul ES5 în sine permite posibilitatea unui comportament necorespunzător al obiectului în raport cu această operațiune (a se vedea §8.6.2).

Prin urmare, este important să testați metodele Array.prototype în fiecare runtime (browser) în care intenționați să utilizați aplicația.

  • I. Buclarea prin matrice reale
    1. Pentru fiecare și metode conexe
    2. Pentru buclă
    3. Utilizarea corectă a pentru ... în buclă
    4. Pentru ... de buclă (utilizarea implicită a unui iterator)
    5. Utilizarea explicită a unui iterator
  • II. În buclă prin obiecte de tip matrice
    1. Folosind metode pentru a itera peste matrice reale
    2. Conversia într-o matrice reală
    3. O notă despre obiectele de execuție

I. Iterarea asupra matricelor reale

În acest moment, există trei moduri de a itera peste elementele unui tablou real:

  1. array.prototype.forEach fiecare metodă;
  2. clasic pentru bucla;
  3. Un bine format pentru ... în buclă.

În plus, în curând, odată cu apariția noului standard ECMAScript 6 (ES 6), se așteaptă încă două modalități:

  1. pentru ... de buclă (utilizarea implicită a unui iterator);
  2. utilizarea explicită a unui iterator.

1. Metoda forEach și metodele conexe

Dacă proiectul dvs. este conceput pentru a susține capabilitățile standardului ECMAScript 5 (ES5), puteți utiliza una dintre inovațiile sale - metoda forEach.

Exemplu de utilizare:

Var a \u003d ["a", "b", "c"]; a.forEach (function (entry) (console.log (entry);));

În general, utilizarea forEach necesită conectarea bibliotecii de emulare es5-shim pentru browserele care nu au suport nativ pentru această metodă. Acestea includ IE 8 și versiunile anterioare, care sunt încă în uz astăzi.

Avantajul forEach este că nu este nevoie să declarați variabile locale pentru a stoca indexul și valoarea elementului matrice curent, deoarece acestea sunt transmise automat la funcția de apel invers ca argumente.

Dacă sunteți îngrijorat de costul potențial al apelării unui apel invers pentru fiecare articol, nu vă faceți griji și citiți acest lucru.

forEach este conceput pentru a itera peste toate elementele unui tablou, dar pe lângă acesta ES5 oferă mai multe metode mai utile pentru iterarea asupra tuturor sau a unora dintre elemente, plus efectuarea unor acțiuni cu acestea:

  • every - returnează true dacă pentru fiecare element al matricei callback returnează o valoare care este exprimată la true.
  • some - returnează true dacă pentru cel puțin un element al matricei callback returnează o valoare care este exprimată la true.
  • filtru - creează o nouă matrice care conține acele elemente ale matricei originale pentru care returnarea apelului returnează adevărat.
  • hartă - creează o nouă matrice care conține valorile returnate de apelul invers.
  • reduce - reduce o matrice la o singură valoare, aplicând un callback pe rând la fiecare element al matricei, începând cu primul (poate fi util pentru calcularea sumei elementelor matricei și a altor funcții finale).
  • reduceRight - Funcționează similar cu reduce, dar repetă elementele în ordine inversă.

2. Bucla for

Vechi pentru reguli:

Var a \u003d ["a", "b", "c"]; index var; for (index \u003d 0; index< a.length; ++index) { console.log(a); }

Dacă lungimea matricei nu se schimbă pe întreaga buclă, iar bucla în sine aparține unei bucăți de cod critice pentru performanță (ceea ce este puțin probabil), atunci puteți utiliza versiunea „mai optimă” a pentru cu stocarea lungimii matricei:

Var a \u003d ["a", "b", "c"]; var index, len; for (index \u003d 0, len \u003d a.length; index< len; ++index) { console.log(a); }

În teorie, acest cod ar trebui să ruleze puțin mai rapid decât cel anterior.

Dacă ordinea de iterație nu este importantă, atunci puteți merge chiar mai departe în ceea ce privește optimizarea și a scăpa de variabila pentru stocarea lungimii tabloului prin schimbarea ordinii de iterație la opus:

Var a \u003d ["a", "b", "c"]; index var; for (index \u003d a.length - 1; index\u003e \u003d 0; --index) (console.log (a);)

Cu toate acestea, în motoarele JavaScript moderne, aceste jocuri optimizate nu înseamnă de obicei nimic.

3. Utilizarea corectă a buclei pentru ... în buclă

Dacă vi se recomandă să utilizați o buclă pentru ... în buclă, amintiți-vă că iterarea peste tablouri nu este destinată. Contrar concepției greșite obișnuite, bucla for ... in nu se repetă peste indicii matricei, ci proprietățile enumerate ale obiectului.

Cu toate acestea, în unele cazuri, cum ar fi iterarea peste matrice rare, pentru ... in poate fi utilă, atâta timp cât luați unele precauții, așa cum se arată în exemplul de mai jos:

// a este un tablou rar var a \u003d; a \u003d "a"; a \u003d "b"; a \u003d "c"; for (var key in a) (if (a.hasOwnProperty (key) && /^0$|^d*$/.test(key) && key<= 4294967294) { console.log(a); } }

În acest exemplu, la fiecare iterație a buclei, se efectuează două verificări:

  1. că matricea are propria proprietate numită cheie (care nu este moștenită de la prototipul său).
  2. acea cheie este un șir care conține notația zecimală a unui număr întreg a cărui valoare este mai mică de 4294967294. De unde vine ultimul număr? Din definiția unui index de matrice în ES5, ceea ce implică faptul că cel mai mare indice pe care îl poate avea un element dintr-o matrice este (2 ^ 32 - 2) \u003d 4294967294.

Desigur, astfel de verificări vor ocupa timp suplimentar la executarea buclei. Dar, în cazul unei matrici rare, această metodă este mai eficientă decât o buclă for, deoarece în acest caz sunt repetate doar acele elemente care sunt definite în mod explicit în matrice. Deci, în exemplul de mai sus, vor fi efectuate doar 3 iterații (pentru indicii 0, 10 și 10000) - versus 10001 în bucla for.

Pentru a nu scrie un cod atât de greoi de verificări de fiecare dată când trebuie să iterați pe o matrice, îl puteți proiecta ca o funcție separată:

Funcție arrayHasOwnIndex (matrice, cheie) (returnare array.hasOwnProperty (cheie) && /^0$|^d*$/.test(key) && key<= 4294967294; }

Apoi corpul buclei din exemplu va fi redus semnificativ:

Pentru (cheie în a) (dacă (arrayHasOwnIndex (a, cheie)) (console.log (a);))

Codul de verificare de mai sus este universal, potrivit pentru toate cazurile. Dar, în schimb, puteți utiliza o versiune mai scurtă, deși în mod formal nu este complet corectă, dar totuși potrivită pentru majoritatea cazurilor:

Pentru (cheie în a) (dacă (a.hasOwnProperty (cheie) && String (parseInt (cheie, 10)) \u003d\u003d\u003d cheie) (console.log (a);))

4. For ... of loop (utilizarea implicită a unui iterator)

ES6, deși este încă în starea de proiect, ar trebui să introducă iteratorii în JavaScript.

Iterator este un protocol implementat prin obiecte care definește un mod standard de a obține o succesiune de valori (finite sau infinite).
Un obiect are un iterator dacă metoda next () este definită în el - o funcție fără argumente care returnează un obiect cu două proprietăți:

  1. done (boolean) - adevărat dacă iteratorul a ajuns la sfârșitul secvenței care este iterată. În caz contrar, fals.
  2. valoare - definește valoarea returnată de iterator. Poate fi nedefinit (absent) dacă proprietatea realizată este adevărată.

Multe obiecte încorporate, incl. matricele reale au iteratori impliciti. Cea mai simplă modalitate de a utiliza un iterator pe matrici reale este de a folosi noul pentru ... de construct.

Un exemplu de utilizare pentru ... din:

Var val; var a \u003d ["a", "b", "c"]; for (val of a) (console.log (val);)

În exemplul de mai sus, bucla for ... of apelează implicit iteratorul obiectului Array pentru a obține fiecare valoare din matrice.

5. Utilizarea explicită a unui iterator

Iteratorii pot fi folosiți în mod explicit, totuși, în acest caz, codul devine mult mai complex, în comparație cu for ... of loop. Arată așa:

Var a \u003d ["a", "b", "c"]; intrare var; while (! (entry \u003d a.next ()). done) (console.log (entry.value);)

II. Iterează peste obiecte asemănătoare matricei

În plus față de matricele reale, JavaScript conține și obiecte asemănătoare matricei ... Ceea ce au în comun cu matricele reale este că au o proprietate de lungime și proprietăți cu nume sub formă de numere care corespund elementelor matricei. Exemplele includ DOM-ul colecției NodeList și argumentele pseudo-matrice disponibile în cadrul oricărei funcții / metode.

1. Utilizarea metodelor de iterație peste matrice reale

Cel puțin majoritatea, dacă nu toate, metodele de iterație peste matrice reale pot fi utilizate pentru a itera peste obiecte asemănătoare matricei.

Pentru și pentru ... în construcții pot fi aplicate obiectelor asemănătoare matricei exact în același mod ca și matricilor reale.

forEach și alte metode Array.prototype se aplică și obiectelor asemănătoare matricei. Pentru a face acest lucru, utilizați un apel către Function.call sau Function.apply.

De exemplu, dacă doriți să aplicați pentru fiecare la proprietatea childNodes a unui obiect Node, o puteți face astfel:

Array.prototype.forEach.call (node.childNodes, funcție (copil) (// faceți ceva cu obiectul copil));

Pentru ușurința reutilizării acestei tehnici, puteți declara o referință la metoda Array.prototype.forEach într-o variabilă separată și o puteți folosi ca o prescurtare:

// (Aceasta presupune că tot codul de mai jos este în același domeniu) var forEach \u003d Array.prototype.forEach; // ... forEach.call (node.childNodes, function (child) (// face ceva cu obiectul child));

Dacă un obiect asemănător matricei are un iterator, atunci acesta poate fi folosit în mod explicit sau implicit pentru a itera peste obiect în același mod ca și pentru tablourile reale.

2. Convertiți într-o matrice reală

Există, de asemenea, un alt mod foarte simplu de a itera peste un obiect asemănător matricei: convertiți-l într-un tablou real și utilizați oricare dintre metodele de mai sus pentru a itera peste matricele reale. Pentru conversie, puteți utiliza metoda generică Array.prototype.slice, care poate fi aplicată oricărui obiect de tip matrice. Acest lucru se face foarte simplu, așa cum se arată în exemplul de mai jos:

Var trueArray \u003d Array.prototype.slice.call (arrayLikeObject, 0);

De exemplu, dacă doriți să convertiți o colecție NodeList într-o matrice reală, aveți nevoie de cod ca acesta:

Var divs \u003d Array.prototype.slice.call (document.querySelectorAll ("div"), 0);

3. O notă privind obiectele de execuție

Dacă aplicați metode Array.prototype obiectelor runtime (cum ar fi colecțiile DOM), atunci ar trebui să aveți în vedere faptul că aceste metode nu sunt garantate să funcționeze corect în toate mediile de runtime (inclusiv browserele). Depinde de comportamentul unui anumit obiect într-un anumit runtime, mai exact, de modul în care operația abstractă HasProperty este implementată în acest obiect. Problema este că standardul ES5 în sine permite posibilitatea unui comportament incorect al unui obiect în raport cu această operațiune (a se vedea §8.6.2).

Prin urmare, este important să testați metodele Array.prototype în fiecare runtime (browser) în care intenționați să utilizați aplicația.

pentru fiecare () metoda execută o funcție furnizată o dată pentru fiecare element matrice.

Sursa pentru acest exemplu interactiv este stocată într-un depozit GitHub. Dacă doriți să contribuiți la proiectul de exemple interactive, vă rugăm să clonați https://github.com/mdn/interactive-examples și să ne trimiteți o cerere de extragere.

Sintaxă

arr .forEach (callback (currentValue [, index [, array]]) [, thisArg])

Parametrii

callback Funcție de executat pe fiecare element. Acceptă între unul și trei argumente: currentValue Elementul curent care este procesat în matrice. index Opțional Indicele currentValue din matrice. array Opțional Aranjamentul forEach () a fost apelat. thisArg Opțional Valoare de utilizat ca acesta atunci când executați callback.

Valoare returnată

Descriere

forEach () apelează o funcție de apel invers furnizată o dată pentru fiecare element dintr-o matrice în ordine crescătoare. Nu este invocat pentru proprietățile indexului care au fost șterse sau care nu sunt inițializate. (Pentru matrici rare.)

callback este invocat cu trei argumente:

  1. valoarea elementului
  2. indicele elementului
  3. obiectul Array fiind traversat

Dacă un parametru thisArg este furnizat pentru forEach (), acesta va fi folosit ca callback pentru această valoare. Valoarea thisArg observabilă în cele din urmă prin callback este determinată în conformitate cu regulile obișnuite pentru determinarea acestui lucru văzut de o funcție.

Gama de elemente procesate de forEach () este setată înainte de prima invocare a apelului invers. Elementele care sunt anexate la matrice după începerea apelului către forEach () nu vor fi vizitate prin apel invers. Dacă elementele existente ale tabloului sunt modificate sau șterse, valoarea lor, transmisă în apel invers, va fi valoarea la momentul pentru care fiecare () le vizitează; elementele care sunt șterse înainte de a fi vizitate nu sunt vizitate. Dacă elementele care sunt deja vizitate sunt eliminate (de exemplu, folosind shift ()) în timpul iterației, elementele ulterioare vor fi omise. (A se vedea exemplul de mai jos.)

forEach () execută funcția de apel invers o dată pentru fiecare element de matrice; spre deosebire de map () sau reduce () returnează întotdeauna valoarea nedefinită și nu poate fi înlănțuit. Cazul tipic de utilizare este de a executa efecte secundare la sfârșitul unui lanț.

forEach () nu mută matricea pe care este apelat. (Cu toate acestea, apelarea poate face acest lucru)

Nu există nicio modalitate de a opri sau rupe o buclă forEach () decât prin aruncarea unei excepții. Dacă aveți nevoie de un astfel de comportament, metoda forEach () este instrumentul greșit.

Rezilierea anticipată poate fi realizată cu:

Metode de matrice: every (), some (), find () și findIndex () testează elementele matricei cu un predicat care returnează o valoare adevărată pentru a determina dacă este necesară o iterație suplimentară.

Exemple

Nicio operațiune pentru valori neinițializate (tablouri rare)

const arraySparse \u003d let numCallbackRuns \u003d 0 arraySparse.forEach (function (element) (console.log (element) numCallbackRuns ++)) console.log ("numCallbackRuns:", numCallbackRuns) // 1 // 3 // 7 // numCallbackRuns: 3 // comentariu: după cum puteți vedea valoarea lipsă între 3 și 7 nu a invocat funcția de apel invers.

Conversia unei bucle for în forEach

const items \u003d ["item1", "item2", "item3"] const copy \u003d // înainte pentru (let i \u003d 0; i< items.length; i++) { copy.push(items[i]) } // after items.forEach(function(item){ copy.push(item) })

Imprimarea conținutului unui tablou

Notă: Pentru a afișa conținutul unui tablou în consolă, puteți utiliza console.table (), care tipărește o versiune formatată a tabloului.

Următorul exemplu ilustrează o abordare alternativă, folosind forEach ().

Următorul cod înregistrează o linie pentru fiecare element dintr-o matrice:

Funcția logArrayElements (element, index, array) (console.log ("a [" + index + "] \u003d" + element)) // Observați că indexul 2 este omis, deoarece nu există niciun element la // acea poziție în matrice ... .forEach (logArrayElements) // jurnale: // a \u003d 2 // a \u003d 5 // a \u003d 9

Folosind thisArg

Următorul exemplu (inventat) actualizează proprietățile unui obiect din fiecare intrare din matrice:

Function Counter () (this.sum \u003d 0 this.count \u003d 0) Counter.prototype.add \u003d function (array) (array.forEach (function (entry) (this.sum + \u003d entry ++ this.count), this ) // ^ ---- Notă) const obj \u003d new Counter () obj.add () obj.count // 3 obj.sum // 16

Deoarece parametrul thisArg (this) este furnizat pentru forEach (), este trecut la callback de fiecare dată când este invocat. Callback îl folosește ca valoare.

O funcție de copiere obiect

Următorul cod creează o copie a unui obiect dat.

Există diferite moduri de a crea o copie a unui obiect. Următorul este doar un mod și este prezentat pentru a explica modul în care funcționează Array.prototype.forEach () utilizând obiectul ECMAScript 5. * Funcțiile de proprietate Meta.

Function copy (obj) (const copy \u003d Object.create (Object.getPrototypeOf (obj)) const propNames \u003d Object.getOwnPropertyNames (obj) propNames.forEach (function (name) (const desc \u003d Object.getOwnPropertyDescriptor (obj, name) Object .defineProperty (copie, nume, desc))) returnează copie) const obj1 \u003d (a: 1, b: 2) const obj2 \u003d copy (obj1) // obj2 arată ca obiect1 acum

Dacă matricea este modificată în timpul iterației, alte elemente pot fi omise.

Următorul exemplu înregistrează „unu”, „doi”, „patru”.

Când intrarea care conține valoarea "(! LANG: două" is reached, the first entry of the whole array is shifted off-resulting in all remaining entries moving up one position. Because element "four" is now at an earlier position in the array, "three" will be skipped.!}

forEach () nu face o copie a matricei înainte de a itera.

Let words \u003d ["one", "two", "three", "four"] words.forEach (function (word) (console.log (word) if (word \u003d\u003d\u003d "two") (words.shift ( )))) // unul // doi // patru

Aplatizați o matrice

Următorul exemplu este aici doar în scop de învățare. Dacă doriți să aplatizați o matrice utilizând metode încorporate, puteți utiliza Array.prototype.flat () (care se așteaptă să facă parte din ES2019 și este deja implementat în unele browsere).

/ ** * Aplatizează matricea trecută într-o matrice unidimensională * * @params (matrice) arr * @returns (matrice) * / funcție aplatizează (arr) (const result \u003d arr.forEach ((i) \u003d\u003e (if (Matrice isArray (i)) (result.push (... aplatizează (i))) else (result.push (i)))) returnează rezultatul) // Utilizare const problem \u003d, 8, 9]] aplatizează (problemă) / /

Notă despre utilizarea promisiunilor sau funcțiilor asincronizate

let ratings \u003d let sum \u003d 0 let sumFunction \u003d async function (a, b) (return a + b) ratings.forEach (async function (rating) (sum \u003d await sumFunction (sum, rating))) console.log (sum) // Ieșire așteptată: 14 // Ieșire reală: 0

Specificații

Specificație stare cometariu
ECMAScript Ultimul proiect (ECMA-262)
Proiect
ECMAScript 2015 (ediția a 6-a, ECMA-262)
Definiția „Array.prototype.forEach” din specificația respectivă.
Standard
ECMAScript 5.1 (ECMA-262)
Definiția „Array.prototype.forEach” din specificația respectivă.
Standard Definiția inițială. Implementat în JavaScript 1.6.

Compatibilitate browser

Tabelul de compatibilitate din această pagină este generat din date structurate. Dacă doriți să contribuiți la date, consultați https://github.com/mdn/browser-compat-data și trimiteți-ne o cerere de extragere.

Actualizați datele de compatibilitate pe GitHub

DesktopMobilServer
CromMargineFirefoxInternet ExplorerOperăSafariVizualizare web AndroidChrome pentru AndroidFirefox pentru AndroidOpera pentru AndroidSafari pe iOSSamsung InternetNode.js
pentru fiecareChrome Suport complet 1Suport Edge complet 12Suport complet Firefox 1.5IE Suport complet 9Opera Suport complet DaSuport complet Safari 3WebView Android Suport complet ≤37Chrome Android Suport complet 18Suport complet Firefox pentru Android 4Opera Android Suport complet DaSuport complet Safari iOS 1Samsung Internet Android Suport complet 1.0nodejs Suport complet Da

Un articol în care vom analiza exemple de utilizare a jQuery fiecare funcție și metodă.

Biblioteca jQuery are 2 entități diferite denumite fiecare.

Primul (jQuery.each) este o funcție generică jQuery care poate fi utilizată pentru a itera peste elementele unui tablou sau obiect.

Cea de-a doua (fiecare) este o metodă care se aplică unui set de articole pentru a se bucura peste ele.

Fiecare buclă (jQuery.each). Exemple de utilizare

Sintaxa pentru fiecare funcție este:

// matrice sau obiect - o matrice sau un obiect ale cărui elemente sau proprietăți trebuie să fie iterate peste // callback - o funcție care va fi executată pentru fiecare element al proprietății unui array sau obiect $ .each (matrice sau obiect, callback);

Să vedem exemple pentru a lucra cu fiecare funcție.

Exemplul nr. 1. În el, vom itera peste toate elementele matricei.

// o matrice de 3 linii var arr \u003d ["Mașină", \u200b\u200b"Camion", "Autobuz"]; // iterați peste matrice arr $ .each (arr, funcție (index, valoare) (// acțiuni care vor fi efectuate pentru fiecare element al matricei // indexul este indicele curent al elementului matricei (număr) // valoarea este valoarea elementului matricei curente // tipăriți indexul și valoarea matricei pe consola console.log ("Index:" + index + "; Valoare:" + valoare);)); / * Rezultat (în consolă): Index: 0; Valoare: Indicele mașinii: 1; Valoare: Indicele camionului: 2; Valoare: autobuz * /

În codul de mai sus, fiecare funcție este utilizată pentru a itera pe o matrice. Funcția are 2 parametri necesari... Primul parametru este o entitate (matrice sau obiect), ale cărei elemente (proprietăți) trebuie repetate. În acest caz, este matricea arr. Al doilea parametru este o funcție de apel invers care va fi executată pentru fiecare element (în acest caz) al matricei. Are 2 parametri care sunt disponibili în interiorul acestuia prin variabilele corespunzătoare. Primul parametru este numărul ordinal al elementului (numărarea se efectuează de la 0). Al doilea parametru este valoarea elementului matrice curent.

Exemplul nr. 2. În acest exemplu vom itera peste toate proprietățile obiectului.


// obiect smartphone cu 5 proprietăți var smartphone \u003d ("nume": "LG G5 se", "an": "2016", "dimensiune ecran": "5.3", "rezoluție ecran": "2560 x 1440 "," os ":" Android 6.0 (Marshmallow) "); // iterați peste obiectul smartphone $ .each (smartphone, funcție (cheie, valoare) (// acțiuni care vor fi efectuate pentru fiecare proprietate a obiectului // cheie - numele curent al proprietății matricei // valoare - valoarea proprietății curente a obiectului // afișează numele proprietății și valoarea sa la consola console.log ("Proprietate:" + cheie + "; Valoare:" + valoare);)); / * Rezultat (în consolă): Proprietate: nume; Valoare: LG G5 se Proprietate: an; Valoare: 2016 Proprietate: dimensiunea ecranului; Valoare: 5.3 Proprietate: rezoluție ecran; Valoare: 2560 x 1440 Proprietate: os; Valoare: Android 6.0 (Marshmallow) * /

Fiecare funcție poate fi utilizată pentru a itera peste obiecte JavaScript. Diferența în utilizarea sa este doar că parametrii funcției de apel invers au valori diferite. Primul parametru stochează numele proprietății obiect, iar al doilea stochează valoarea acestei proprietăți.

Exemplul nr. 3. În el vom itera o structură mai complexă (să vedem cum să folosim fiecare imbricat).

// un obiect format din 2 proprietăți. Fiecare proprietate a acestui obiect are ca valoare o matrice, ale cărei elemente sunt și obiecte var articles \u003d ("Bootstrap": [("id": "1", "title": "Introducere"), ("id": "2" , "title": "Cum se instalează"), ("id": "3", "title": "Grid")], "JavaScript": [("id": "4", "title": "Noțiuni de bază "), (" id ":" 5 "," title ":" Selecția elementelor ")]); $ .each (articole, funcție (cheie, date) (console.log ("Secțiune:" + cheie); $ .each (date, funcție (index, valoare)) (console.log ("Articol: id \u003d" + valoare ["id"] + "; Title \u003d" + value ["title"]);));)); / * Rezultat: Secțiune: Bootstrap Articol: id \u003d 1; Titlu \u003d Introducere Articol: id \u003d 2; Titlu \u003d Cum se instalează articolul: id \u003d 3; Titlu \u003d Secțiune grilă: Articol JavaScript: id \u003d 4; Titlu \u003d Articol de bază: id \u003d 5; Nume \u003d Selecția elementelor * /

Cum pot întrerupe fiecare (ies din buclă)?

Bucla fiecare este întreruptă cu o instrucțiune return, care trebuie să returneze false.

De exemplu, să întrerupem execuția fiecărei bucle după ce găsim numărul 7 în matricea arr:

// o matrice de 5 numere var arr \u003d; // numărul de găsit var find \u003d 7; // iterați peste matricea arr $ .each (arr, funcție (index, valoare) (// dacă se găsește numărul necesar, atunci .. if (valoare \u003d\u003d\u003d găsiți) (// imprimați-l în consola console.log („Ura! Numărul "+ găsi +" a fost găsit! Acest număr are un index: "+ index); // renunță la executarea buclei returnează fals;) altfel (// în caz contrar, tipăriți numărul curent în consola.log (" Număr curent: "+ valoare); ))); / * Rezultat (în consolă): Număr curent: 5 Număr curent: 4 Ura! Numărul 7 a fost găsit! Acest număr are un indice: 2 * /

Cum merg la următoarea iterație (fiecare continuă)?

În fiecare, executarea iterației curente este întreruptă și trecerea la următoarea se efectuează folosind instrucțiunea return, care trebuie să aibă o altă valoare decât falsă.

// o matrice de numere var arr \u003d; // o matrice care trebuie să conțină toate elementele matricei arr, cu excepția numerelor pare var newarr \u003d; // iterați peste matricea arr $ .each (arr, funcție (index, valoare) (// dacă elementul este egal, apoi săriți-l dacă (valoare% 2 \u003d\u003d\u003d 0) (// întrerupeți iterația curentă și mergeți la următoarea revenire; ) // adaugă valoare matricei newarr newarr.push (valoare);)); console.log ("Original array (arr):" + arr.join ()); console.log ("Matrice de rezultate (newarr):" + newarr.join ()); / * Rezultat (în consolă): Matrice originală (arr): 3,5,4,9,17,19,30,35,40 Matrice de rezultate (newarr): 3,5,9,17,19,35 * /

Iterarea asupra elementelor curente (.each)

Sintaxa pentru fiecare metodă (se aplică numai elementelor selectate):


.fiecare (funcție); // funcție - o funcție care va fi executată pentru fiecare element al obiectului curent

Să vedem cum funcționează metoda.each cu următorul exemplu (iterând peste elemente div):


În exemplul de mai sus, fiecare metodă utilizează setul curent (elemente selectate cu selectorul $ ("div")). Manipulatorul fiecărei metode este întotdeauna o funcție care va fi executată pentru fiecare element al setului curent (în acest caz, pentru fiecare element div). Această funcție are 2 parametri opționali. Unul dintre ele (index) este numărul de secvență al iterației curente, iar al doilea (element) este referința DOM la elementul curent. În plus, acest cuvânt cheie este disponibil în interiorul funcției, care, la fel ca al doilea parametru, conține o referință DOM la elementul curent.

De exemplu, să imprimăm pe consolă valoarea atributului href pentru toate elementele de pe pagină:

$ ("a"). each (function () (console.log ($ (this) .attr ("href"));));

$ ("a"). fiecare (funcție () (var link \u003d $ (this) .attr ("href"); if ((link.indexOf ("http: //") \u003d\u003d 0) || (link .indexOf ("https: //") \u003d\u003d 0)) (console.log ("link href \u003d" + link);))); // Dacă pagina conține următoarele link-uri: // Yandex // Cum funcționează JavaScript? // Bootstrap // Apoi în consolă vom vedea următorul rezultat: // https://www.yandex.ru/ // http://getbootstrap.com/

De exemplu, să aruncăm o privire la cum să parcurgeți fiecare element DOM care are numele clasei (să parcurgem toate elementele aceleiași clase).

Raspberry pi
calcul pe o singură placă
Intel Galileo Gen2
19$
Pine A64 Plus

De exemplu, să ne dăm seama cum să iterați pe toate elementele unei pagini.

De exemplu, să imprimăm valoarea tuturor elementelor de intrare pe pagină.

$ ("input"). each (function () (console.log ($ (this) .val ());));

De exemplu, să repetăm \u200b\u200btoți copiii aflați în ul cu id \u003d "lista mea" (fiecare copil).

  • HTML
  • JavaScript

Să ne uităm la o modalitate de a determina ultimul index (element) în fiecare metodă a jQuery.

// select item var myList \u003d $ ("ul li"); // determinați numărul de elemente din selecția var total \u003d MyList.length; // iterați peste elementele selectate myList.each (funcție (index) (dacă (index \u003d\u003d\u003d total - 1) (// acesta este ultimul element din selecție))));

Nu cu mult timp în urmă, m-a dus la asta JavaScript creează matrice asociativă... Uimitor, nu am mai avut nevoie de el până acum. JavaScript... Am început să caut pe Internet cum să o fac. Și am fost foarte surprins că un număr mare de oameni scriu că acest lucru este imposibil, în JavaScript nu este. Din fericire, mulți ani de experiență mi-au spus că sunt prostii. Așa că până la urmă am aflat cum se creează o matrice asociativă în JavaScript, despre care vă voi spune în acest articol.

Mai jos este codul în care se creează o matrice asociativă, apoi se adaugă încă un element și, în cele din urmă, matricea este iterată prin buclă:

În acest articol, am tratat crearea de matrice asociative, schimbarea lor, precum și enumerarea completă pe parcursul ciclului pentru... Eu personal am folosit matrici asociative în JavaScript o singură dată, dar trebuie să fii conștient de o astfel de posibilitate.