Cum pot buclă prin toate intrările într-o matrice folosind JavaScript?
Am crezut că a fost ceva de genul:
forEach(instance in theArray)
Unde theArray` este matricea mea, dar acest lucru pare a fi incorecte.
TL;DR
de-in
dacă nu-l utilizați cu garanții sau sunt măcar conștienți de ce s-ar putea să te muște. Matrice#forEach
(spec
| MDN
) (sau rudele sale "unele" și astfel) (ES5+ numai), de-in
cu garanții.
Dar nu's *o mulțime *** mai mult pentru a explora, citiți mai departe... JavaScript are puternice semantica pentru looping prin tablouri și matrice ca obiecte. Am'am împărțit răspunsul în două părți: Opțiuni pentru veritabilă matrice, și opțiuni pentru lucruri care sunt doar array-ca, cum ar fi "argumente" de obiect, alte iterable obiecte (ES2015+), DOM colecții, și așa mai departe. Am'll rapid rețineți că puteți utiliza ES2015 opțiuni acum, chiar pe ES5 motoare, de transpiling ES2015 să ES5. Căutare pentru "ES2015 transpiling" / "ES6 transpiling" pentru mai multe... Bine, las's se uite la opțiunile noastre:
Ai trei opțiuni în ECMAScript 5 ("ES5"), versiunea cea mai larg acceptată în momentul de față, și două mai adăugat în ECMAScript 2015 ("ES2015", "ES6"):
de-in
corect de-a
(foloseste un iterator implicit) (ES2015+) În orice vag-mediu modern (deci, nu IE8) în cazul în care aveți acces la "Matrice" caracteristici adăugate de către ES5 (direct sau folosind polyfills), puteți folosi "forEach" (spec
| MDN
):
var a = ["a", "b", "c"];
a.forEach(function(entry) {
console.log(entry);
});
"forEach" acceptă o funcție de apel invers și, opțional, o valoare a folosi ca "asta", atunci când apel ca apel invers (nu sunt folosite de mai sus). Callback este apelată pentru fiecare intrare în serie, în ordine, sărind peste inexistente intrări în tablouri rare. Deși am folosit doar un singur argument de mai sus, callback este apelată cu trei: valoarea de fiecare intrare, indicele de intrare, și o referire la matricea're iterarea peste (în cazul în care funcția nu't au deja la îndemână). Dacă nu're sprijinirea învechite browsere, cum ar fi IE8 (care NetApps prezinta la peste 4% cota de piață ca din acest scris, în septembrie 2016), puteți folosi fericit "forEach" în general-scop, o pagină web fără un shim. Dacă aveți nevoie pentru a sprijini învechite browsere, shimming/polyfilling "forEach" este foarte usor de facut (de căutare pentru "es5 shim" pentru mai multe opțiuni). "forEach" are avantajul că nu't trebuie să declare indexare și valoarea variabile în conținut de aplicare, cum se're furnizate ca argumente la funcția de repetare, și atât de frumos luneta doar ca repetare. Daca're îngrijorat de execuție costul de a face un apel de funcție pentru fiecare vector de intrare, don't fi; detalii. În plus, "forEach" este "bucla prin-le pe toate" funcție, dar ES5 definite mai multe alte utile "locul de muncă-ți de drum prin matrice și de a face lucruri" funcții, inclusiv:
fiecare
(se oprește looping prima dată callback returneaza "false" sau ceva falsey) ceva
(se oprește looping prima dată apel invers returnează "adevărat" sau ceva sinceră) filtru
(creează o nouă matrice, inclusiv elemente în cazul în care filtrul funcția returnează "adevărat" și omițând cele în care se întoarce "false") harta
(creează o nouă matrice de valori returnate de apel invers) reduce
(se acumulează o valoare de care apelează în mod repetat apel invers, trecerea de la valorile anterioare; vezi spec pentru detalii; util pentru însumarea cuprins de o matrice și multe alte lucruri)reduceRight
(cum ar fi "reduce", dar funcționează în ordine descrescătoare, mai degrabă decât ordine crescătoare) Uneori metodele vechi sunt cele mai bune:
var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
console.log(a[index]);
}
Dacă lungimea de matrice a câștigat't schimba în buclă, și-l's de performanță sensibile cod (puțin probabil), un pic mai complicat versiune hapsân lungimea în față ar putea fi o mica mai repede:
var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
console.log(a[index]);
}
Și/sau numărare înapoi:
var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
console.log(a[index]);
}
Dar cu moderne JavaScript motoare, l's rare aveți nevoie să prelungim ultimul pic de suc. În ES2015 și mai mare, puteți face index și valoare variabile locale la "pentru" bucla:
let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
let value = a[index];
console.log(index, value);
}
//console.log(index); // would cause "ReferenceError: index is not defined"
//console.log(value); // would cause "ReferenceError: value is not defined"
let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
let value = a[index];
console.log(index, value);
}
try {
console.log(index);
} catch (e) {
console.error(e); // "ReferenceError: index is not defined"
}
try {
console.log(value);
} catch (e) {
console.error(e); // "ReferenceError: value is not defined"
}
Și când faci asta, nu doar "valoare", dar, de asemenea, "index" este recreat pentru fiecare buclă iterație, în sensul de închidere a creat în corpul buclei să păstreze o referință la "index" (și "valoare") creat pentru o anumită iterație:
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
divs[index].addEventListener('click', e => {
console.log("Index is: " + index);
});
}
let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
divs[index].addEventListener('click', e => {
console.log("Index is: " + index);
});
}
<div>zero</div>
<div>one</div>
<div>two</div>
<div>three</div>
<div>four</div>
Dacă ai avut cinci divs, ai'd a obține "Indicele este: 0" dacă ați făcut clic pe primul și "Indicele este: 4" dacă ați făcut clic pe ultimul. Acest lucru nu funcționa dacă utilizați var în loc de
lasa`.
de-in
corectTe'll a obține oameni spunându-vă să utilizați de-in
, dar că's nu ce de-in
pentru. de-in
bucle prin nenumărate proprietăți a unui obiect, nu indici de o matrice. Ordinea nu este garantat, nu chiar în ES2015 (ES6). ES2015+ definește un ordin de proprietăți obiect (prin [[OwnPropertyKeys]]
, [[Enumerate]]
și lucrurile pe care le utilizați, cum ar fi de Obiect.getOwnPropertyKeys
), dar nu nu definirea că de-in
vor urma ordinea asta. (Detalii în acest alt răspuns.)
Singurele cazuri de utilizare pentru de-in
pe o matrice sunt:
de-in
pentru a vizita acele sparese elementele de matrice dacă utilizați garanții corespunzătoare:
// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
if (a.hasOwnProperty(key) && // These checks are
/^0$|^[1-9]\d*$/.test(key) && // explained
key <= 4294967294 // below
) {
console.log(a[key]);
}
}
Rețineți cele trei verificări:
// Utility function for antiquated environments without `forEach`
var hasOwn = Object.prototype.hasOwnProperty;
var rexNum = /^0$|^[1-9]\d*$/;
function sparseEach(array, callback, thisArg) {
var index;
for (var key in array) {
index = +key;
if (hasOwn.call(a, key) &&
rexNum.test(key) &&
index <= 4294967294
) {
callback.call(thisArg, array[key], index, array);
}
}
}
var a = [];
a[5] = "five";
a[10] = "ten";
a[100000] = "one hundred thousand";
a.b = "bee";
sparseEach(a, function(value, index) {
console.log("Value at " + index + " is " + value);
});
de-a
(foloseste un iterator implicit) (ES2015+)ES2015 adaugă iteratori pentru JavaScript. Cel mai simplu mod de a utiliza iteratori este nou pentru-a` declarație. Se pare ca acest lucru:
const a = ["a", "b", "c"];
for (const val of a) {
console.log(val);
}
Sub pătură, care devine o iterator din matrice și bucle prin ea, obtinerea de valori de la ea. Asta nu't au problema asta folosind de-in
a, pentru ca foloseste un iterator definite de obiect (matrice), și tablouri defini lor iteratori itera prin intermediul lor intrări (nu proprietățile lor). Spre deosebire de-in
în ES5, ordinea în care înregistrările sunt vizitate este ordinea numerică a acestora indici.
Uneori, ați putea dori să utilizați un iterator în mod explicit. Puteți face, de asemenea, deși l's o mulțime clunkier decât pentru-a`. Se pare ca acest lucru:
const a = ["a", "b", "c"];
const it = a.values();
let entry;
while (!(entry = it.next()).done) {
console.log(entry.value);
}
Iterator este un obiect de potrivire Iterator definirea în caietul de sarcini. Sale "next" metoda returneaza un nou rezultat obiect de fiecare dată când te sun. Rezultatul obiect are o proprietate, "făcut", spune-ne dacă-l's de făcut, și o proprietate "valoare" cu valoarea pentru care iterație. ("done" este opțional, dacă ar fi "false", "valoare" este opțional, dacă ar fi "nedefinit".) Sensul de "valoare" variază în funcție de iterator; tablouri de sprijin (cel puțin) trei funcții care returnează iteratori:
: Aceasta este cea pe care am folosit-o mai sus. Se întoarce un iterator în cazul în care fiecare "valoare" este matrice de intrare pentru care iterație (
"o",
"b" și"c" în exemplul anterior). : Returnează un iterator în cazul în care fiecare "valoare" este cheia pentru ca repetare (deci pentru a " a " de mai sus, care ar fi"0"", apoi " "1"", apoi " "2"
). intrări()
: Returnează un iterator în cazul în care fiecare "valoare" este o matrice în formă [cheie, valoare]
pentru că iterație. În afară de adevărata matrice, există, de asemenea, matrice-ca obiecte care au o "lungime" de proprietate și proprietăți numerice cu numele: NodeList
cazuri, "argumente" de obiect, etc. Cum putem bucla prin conținutul lor?
Cel puțin o parte, și, eventual, cele mai multe sau chiar toate, de matrice abordări de mai sus frecvent se aplică la fel de bine să matrice-obiecte cum ar fi:
Utilizați "forEach" și conexe (ES5+)
Diferitele funcții pe Matrice.prototipsunt "în mod intenționat generic" și, de obicei, poate fi folosit pe array-ca obiecte prin intermediul [
Funcția de apel#] [15] sau [Funcția#aplica
]16. (A se vedea Avertisment pentru host-cu condiția obiecte la sfârșitul acestui răspuns, dar's o problemă rară.)
Să presupunem că ai vrut să utilizați "forEach" pe un Nod
's `childNodes de proprietate. Te'd a face acest lucru:
Matrice.prototip.forEach.apel(nod.childNodes, funcția(copil) {
// Facem ceva cu "copil"
});
Daca're de gând să fac asta de mult, ați putea dori să luați o copie de funcția de referință într-o variabilă pentru reutilizare, de exemplu:
// (Acest lucru este, probabil, în unele definire a funcției)
var forEach = Array.prototip.forEach;
// Apoi, mai târziu...
forEach.apel(nod.childNodes, funcția(copil) {
// Facem ceva cu "copil"
});
Utilizați un simplu "pentru" buclă Evident, un simplu "pentru" bucla se aplică la matrice ca obiecte.
Utilizarea de-in
corect
de-in
cu aceleași garanții ca și cu o matrice ar trebui să lucreze cu array-ca obiecte precum; avertismentul pentru host-obiecte oferite pe #1 de mai sus se pot aplica.
Utilizarea pentru-a` (foloseste un iterator implicit) (ES2015+)
de-a
va utiliza iterator furnizate de obiect (dacă este cazul); ne'll trebuie să vedem cum joacă cu diverse matrice de obiecte similare, în special-gazdă cu condiția altele. De exemplu, caietul de sarcini pentru NodeList "de la" querySelectorAll
a fost actualizat pentru a sprijini iterație. Spec pentru HTMLCollection "de la" getElementsByTagName
nu a fost.
Utilizați un iterator în mod explicit (ES2015+) Vezi #4, am'll trebuie să vedem cum iteratori juca.
Alte ori, poate doriți pentru a converti o serie obiect ca într-o adevărată matrice. A face asta este surprinzător de ușor:
Folosi felie
metoda de matrice
Putem folosi felie
metoda de matrice, care la fel ca celelalte metode menționate mai sus este "în mod intenționat generic" și astfel poate fi folosit cu matrice de obiecte, astfel:
var trueArray = Array.prototip.felie.apel(arrayLikeObject);
Deci, de exemplu, dacă vrem să converti un NodeList` într-o adevărată matrice, am putea face acest lucru:
var divs = Array.prototip.felie.apel(document.querySelectorAll("div"));
Vezi Avertisment pentru host-cu condiția obiecte mai jos. În special, rețineți că acest lucru va eșua în IE8 și mai devreme, care nu't să utilizați-gazdă cu condiția obiecte ca "asta" de genul asta.
Folosi răspândirea sintaxă (...
)
L's, de asemenea, posibil să se utilizeze ES2015's răspândirea sintaxa cu JavaScript motoare care acceptă această caracteristică:
var trueArray = [...iterableObject];
Deci, de exemplu, dacă vrem să converti un NodeList` într-o adevărată matrice, cu răspândirea sintaxa acest lucru devine destul de succint:
var divs = [...document.querySelectorAll("div")];
Utilizarea Matrice.din
(spec) | (MDN)
Matrice.din
(ES2015+, dar ușor de polyfilled) creează o matrice dintr-o matrice-ca obiect, opțional trece intrările printr-o funcție de cartografiere în primul rând. Deci:
var divs = Array.din(document.querySelectorAll("div"));
Sau, dacă ai vrut pentru a obține o serie de tag-ul nume de elemente cu o anumită clasă,'d utiliza funcția de cartografiere:
// Săgeată funcția (ES2015):
var divs = Array.din(document.querySelectorAll(".unele-clasa"), element => element.tagName);
// Funcția Standard (din Matrice.din` poate fi shimmed):
var divs = Array.din(document.querySelectorAll(".unele-clasa"), funcția(element) {
reveni element.tagName;
});
Dacă utilizați Matrice.prototip
funcții cu -gazdă cu condiția matrice-ca obiecte (DOM liste și alte lucruri oferite de browser-ul, mai degrabă decât motorul JavaScript), trebuie să fie sigur de a testa în țintă medii pentru a asigurați-gazdă cu condiția obiect se comportă în mod corespunzător. Cele mai multe nu se comporte în mod corespunzător (acum), dar's important pentru a testa. Motivul este că cele mai multe din Matrice.prototipmetode te're ar putea să doriți să utilizați se bazează pe host-condiția de obiect a da un răspuns sincer la abstract [
[[HasProperty]]`]19 operațiune. Ca din acest scris, browsere face o treabă foarte bună, dar 5.1 spec v-a permite posibilitatea de o gazdă cu condiția obiect nu poate fi sincer. L's, în §8.6.2, mai multe paragrafe mai jos, masă, lângă începutul acestei secțiuni), unde se spune:
Gazdă obiecte ce pot pune în aplicare aceste metode de interne, în orice mod, cu excepția cazului în care se specifică altfel; de exemplu, o posibilitate este că
[[Get]] " și " [[Pus]]
pentru o anumită gazdă obiect, într-adevăr, descărca și stoca valorile de proprietate, dar[[HasProperty]]
generează întotdeauna fals. (I n't găsi echivalentul verbiaj în ES2015 spec, dar's va fi cazul.) Din nou, ca din acest scris comune-gazdă cu condiția matrice-ca obiecte în browserele moderne [NodeList
cazuri, de exemplu] nu ocup[[HasProperty]]
corect, dar's important pentru a testa.)
Notă: Acest răspuns este iremediabil out-of-data. Pentru o abordare mai modernă, uita-te la metodele disponibile pe o serie. Metodele de interes ar putea fi:
Modul standard de a repeta o matrice în JavaScript este o vanilie "pentru" -bucla:
var length = arr.length,
element = null;
for (var i = 0; i < length; i++) {
element = arr[i];
// Do something with element
}
Rețineți, totuși, că această abordare este bună doar dacă ai o matrice densa, și fiecare indice este ocupat de un element. Dacă o matrice este rară, atunci puteți rula în probleme de performanță cu această abordare, deoarece va repeta peste o mulțime de indici care nu într-adevăr există în matrice. În acest caz, pentru .. în buclă ar putea fi o idee mai bună. Cu toate acestea**, trebuie să utilizați garanții adecvate pentru a se asigura că numai proprietățile dorite de matrice (care este, elementele de matrice) au acționat, încă din anii pentru..în buclă va fi, de asemenea, enumerate în moștenirea browsere, sau daca proprietăți suplimentare sunt definite ca
enumerable`.
În ECMAScript 5 nu va fi un forEach metoda pe matrice de prototip, dar acesta nu este acceptat în moștenirea browsere. Deci, pentru a fi capabil să-l folosească în mod constant trebuie să fie un mediu care acceptă (de exemplu, Node.js pentru server side JavaScript), sau de a folosi un "Polyfill". La Polyfill pentru această funcționalitate este, cu toate acestea, banal și de a face codul mai ușor de citit, este un bun polyfill pentru a include.
Dacă utilizați jQuery, bibliotecă, puteți utiliza jQuery.fiecare:
$.each(yourArray, function(index, value) {
// do your stuff here
});
EDIT :
După fiecare întrebare, utilizatorul vrea cod în javascript în loc de jquery atât de editare este
var length = yourArray.length;
for (var i = 0; i < length; i++) {
// Do something with yourArray[i].
}
Cred că invers pentru bucla merită o mențiune aici:
for (var i = array.length; i--; ) {
// process array[i]
}
forEach()
și să ES6's pentru ... de
. Unii dezvoltatori utilizarea inversă pentru buclă implicit, dacă nu există un motiv bun pentru a bucla înainte. Deși câștiguri de performanță sunt de obicei nesemnificative, este un fel de țipete:
"Doar a face acest lucru pentru fiecare element din lista, nu't grijă despre ordinea!" Cu toate acestea, în practică, că este nu de fapt o indicație de încredere de intenție, deoarece este imposibil de distins de acele ocazii, atunci când nu grijă despre scopul, și chiar nu trebuie la bucla in sens invers. Deci, în fapt, un alt construct ar fi necesare pentru a exprima exact "nu't de îngrijire a" intenție, ceva disponibilă în prezent în cele mai multe limbi, inclusiv ECMAScript, dar care ar putea fi numit, de exemplu,
forEachUnordered()
. Dacă scopul nu't contează, și eficiență este un motiv de îngrijorare (în cele mai intime buclă de un joc sau motor de animație), atunci acesta poate fi acceptabilă utilizarea inversă pentru bucla de du-te-pentru model. Doar amintiți-vă că văd un revers pentru bucla din codul existent nu înseamnă neapărat că ordinea irelevant!Era mai bine să utilizați forEach()
În general, de nivel superior codul de unde claritate și siguranță sunt mai mari preocupări, mi-a fost recomandat anterior, folosind
Array::forEach
ca implicit model pentru looping (deși în aceste zile eu prefer să folosesc pentru..de`). Motive pentru a prefera "forEach" peste o buclă inversă sunt:
pentru
și în timp ce
bucle). Există o dezbatere cu privire la posibilitatea pentru..a " sau " forEach()
sunt de preferat:
așteaptă
nu funcționează în interiorul forEach()
. Folosind pentru..aeste [cel mai clar model](https://github.com/airbnb/javascript/issues/1122#issuecomment-259876436) în acest caz. Personal, am tendința de a folosi orice pare mai simplu de a citi, dacă nu de performanță sau de minimizare a devenit o preocupare majoră. Deci, în aceste zile eu prefer să folosesc pentru..a "în loc de" forEach()
, dar nu va folosi întotdeauna "hartă" sau "filtru" sau ["găsi"] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) sau ceva
atunci când este cazul.
(De dragul de colegii mei, eu folosesc rar reduce
.) for (var i = 0; i < array.length; i++) { ... } // Forwards
for (var i = array.length; i--; ) { ... } // Reverse
Veți observa că i -
este mijlocul clauze (în cazul în care vom vedea, de obicei, o comparație) și ultima propoziție este gol (în cazul în care vom vedea, de obicei, i++
). Asta înseamnă că i -
este, de asemenea, utilizat ca stare pentru continuare. În mod esențial, este executată și verificată înainte fiecare iterație.
i -
ruleaza înainte fiecare iterație, în prima iterație ne va fi de fapt accesarea element în matrice.lungime - 1` care evită orice probleme cu <grevă>Matrice-out-of-limite "nedefinit" elemente. i -
se evaluează la un falsey valoare (atunci când se produce 0).
Trucul este că, spre deosebire de --eu
oscilant i -
operator diminuări de "i", dar dă valoare înainte de de decrementare. Consola poate demonstra acest lucru:
> var i = 5; [i, eu..., am];
[5, 5, 4]
Deci, în ultima iterație, i a fost anterior 1 și i -
expresie modificări la 0 dar, de fapt, randamentele 1 (sinceră), și deci condiția trece. Pe următoarea iterație i -
modificările i a -1 dar randamentele 0 (falsey), provocând execuție să renunțe imediat din partea de jos a buclei.
În tradiționale înainte de buclă, i++ " și " ++i
sunt interschimbabile (ca Douglas Crockford puncte). Cu toate acestea, în marșarier pentru buclă, pentru că decrementare este, de asemenea, starea noastră de exprimare, trebuie să rămânem cu i -
dacă vrem să proceseze element la indicele 0. Unii oameni le place pentru a trage o sageata mica in reverse "pentru", buclă, și se încheie cu un cadou:
for (var i = array.length; i --> 0 ;) {
Du-te la credite WYL mi-a arătat beneficiile și ororile inversă de curent.
Unele C-stil limbi folosesc "foreach" pentru a bucla prin enumerări. În JavaScript se face cu `pentru..în structura de buclă:
var index,
value;
for (index in obj) {
value = obj[index];
}
Există o captură. pentru..în` va bucla prin fiecare obiect's enumerable membrii și membrii de pe prototipul său. Pentru a evita citirea valorilor care sunt moștenite prin obiect's prototipul, pur și simplu a verifica în cazul în care proprietatea aparține obiect:
for (i in obj) {
if (obj.hasOwnProperty(i)) {
//do stuff
}
}
În plus, ECMAScript 5 a adăugat o "forEach" metoda de a `Matrice.prototip care poate fi folosit pentru a enumera peste o matrice folosind un calback (cu polyfill este în docs astfel încât să puteți utiliza în continuare pentru browsere mai vechi):
arr.forEach(function (val, index, theArray) {
//do stuff
});
L's important să rețineți că, Matrice.prototip.forEach
nu't rupe atunci când callback returneaza "false". jQuery și Underscore.js furnizeze propriile lor variante pe fiecare
pentru a oferi bucle care pot fi scurt-circuitat.
Dacă doriți să buclă pe o matrice, utilizare standard de trei-parte "pentru" bucla.
for (var i = 0; i < myArray.length; i++) {
var arrayItem = myArray[i];
}
Puteți obține unele optimizări de performanță de cache `myArray.lungimea sau iterarea peste invers.
Stiu ca e un post vechi, și există atât de multe răspunsuri mari deja. Pentru un pic mai mult de exhaustivitate m-am gândit'd arunca în altul folosind AngularJS. Desigur, aceasta se aplică numai dacă're folosind Unghiulare, evident, cu toate acestea, am'd ca a pus-o oricum.
unghiulară.forEach
are 2 argumente și, opțional, un al treilea argument. Primul argument este obiectul (matrice) pentru a itera peste, cel de-al doilea argument este funcție de iterator, și opțional al treilea argument este contextul object (de fapt menționată în interiorul buclei, ca 'asta'.
Există diferite moduri de a folosi forEach buclă unghiulare. Cea mai simplă și, probabil, cel mai utilizat este
var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
//item will be each element in the array
//do something
});
Un alt mod care este util pentru copierea de articole de la un tablou la altul este
var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);
Totuși, nu't trebuie să faci asta, pur și simplu, puteți face următoarele și-l's echivalente pentru exemplul anterior:
angular.forEach(temp, function(item) {
temp2.push(item);
});
Acum există argumente pro și contra de a folosi unghiulară.forEach
funcție de cum s-a construit în cu aromă de vanilie "pentru" bucla.
Pro
Luați în considerare următoarele 2 bucle imbricate, care face exact același lucru. Las's spun ca am 2 tablouri de obiecte și fiecare obiect conține o serie de rezultate, fiecare dintre care are o Valoare de proprietate, care's un șir de caractere (sau orice altceva). Și să's a spus am nevoie pentru a repeta peste fiecare dintre rezultatele și dacă au're egale, atunci pentru a efectua o acțiune:
angular.forEach(obj1.results, function(result1) {
angular.forEach(obj2.results, function(result2) {
if (result1.Value === result2.Value) {
//do something
}
});
});
//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
for (var j = 0; j < obj2.results.length; j++) {
if (obj1.results[i].Value === obj2.results[j].Value) {
//do something
}
}
}
Acordate acesta este un foarte simplu exemplu ipotetic, dar am'am scris triple încorporat pentru bucle folosind cea de a doua abordare și era foarte greu de citit, și de a scrie pentru care contează.
Contra
unghiulară.forEach
, și nativ "forEach", pentru care contează, sunt atât de mult mai lent decât în mod normal "pentru" bucla....despre 90% mai lent. Deci pentru seturi mari de date, mai bine să rămânem la nativ "pentru" bucla.unghiulară.forEach
ai pune simplu un retur; declarația în funcție de ca unghiulară.forEach(matrice, funcția(postul) { dacă (someConditionIsTrue) return; });
care va face ca acesta să continue din funcție pentru că iterație. Acest lucru este, de asemenea, datorită faptului că nativ "forEach" nu are suport break sau continue.Am'm sigur că nu's diverse alte argumente pro și contra, precum și, și vă rugăm să nu ezitați să adăugați orice ca tu de cuviință. Simt că, în concluzie, dacă aveți nevoie de eficiență, rămânem doar cu nativ "pentru" bucla pentru looping are nevoie. Dar, în cazul seturilor de date sunt mai mici și o eficiență este bine să dea în schimb pentru lizibilitate și writability, apoi prin toate mijloacele arunca un unghiulare.forEach în care băiatul rău.
O forEach punerea în aplicare (a[a se vedea în jsFiddle][1]):
function forEach(list,callback) {
var length = list.length;
for (var n = 0; n < length; n++) {
callback.call(list[n]);
}
}
var myArray = ['hello','world'];
forEach(
myArray,
function(){
alert(this); // do something
}
);
Dacă tu nu't mintea golirea matrice:
var x;
while(x = y.pop()){
alert(x); //do something
}
"x" va conține ultima valoare de " y " și va fi eliminat din matrice. Puteți folosi, de asemenea, shift()
care va oferi și elimina primul element de "y".
O soluție simplă ar fi să utilizați underscore.js biblioteca. L's furnizarea de mai multe instrumente utile, cum ar fi fiecare
si automat va delega locuri de muncă în native "forEach", dacă este disponibil.
O CodePen exemplu a modului în care funcționează este:
var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});
Matrice.prototip.forEach()
.Există trei implementări de "foreach" în jQuery, după cum urmează.
var a = [3,2];
$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3
Ca Valoare de 6:
list = [0, 1, 2, 3]
for (let obj of list) {
console.log(obj)
}
În cazul în care " de "evită ciudățenii asociat cu" în "și face să funcționeze ca "pentru" bucla de orice altă limbă, și să
se leaga eu
în buclă spre deosebire de cadrul funcției.
Acolade ({}
) poate fi omis atunci când există doar o singură comandă (de exemplu, în exemplul de mai sus).
Probabil pentru(i = 0; i < matrice.length; i++)` bucla nu este cea mai buna alegere. De ce? Dacă aveți acest lucru:
var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";
Metoda va suna din matrice[0] " cu " matrice[2]`. În primul rând, acest lucru va prima referință variabile nu't chiar trebuie, a doua nu ar avea variabile în matrice, și a treia, acest lucru va face codul mai îndrăznețe. Uite aici, l's de ce am folosit:
for(var i in array){
var el = array[i];
//If you want 'i' to be INT just put parseInt(i)
//Do something with el
}
Și dacă vrei să fie o funcție, puteți face acest lucru:
function foreach(array, call){
for(var i in array){
call(array[i]);
}
}
Dacă doriți să rupă, un pic mai logica:
function foreach(array, call){
for(var i in array){
if(call(array[i]) == false){
break;
}
}
}
Exemplu:
foreach(array, function(el){
if(el != "!"){
console.log(el);
} else {
console.log(el+"!!");
}
});
Se întoarce:
//Hello
//World
//!!!
Nu e't orice `pentru fiecare buclă în nativ JavaScript. Puteți folosi fie biblioteci pentru a obține această funcționalitate (eu recomand Underscore.js), utilizați un simplu "pentru", în buclă.
for (var instance in objects) {
...
}
Cu toate acestea, rețineți că pot exista motive pentru a utiliza chiar și un simplu "pentru" bucla (vezi Stack Overflow întrebare Ce este cu "for...in" cu matrice repetare o idee rea?)
var instance;
for (var i=0; i < objects.length; i++) {
var instance = objects[i];
...
}
Acesta este un iterator pentru NON-rare listă în cazul în care indexul incepe de la 0, care este scenariul tipic atunci când se ocupă cu document.getElementsByTagName sau document.querySelectorAll)
function each( fn, data ) {
if(typeof fn == 'string')
eval('fn = function(data, i){' + fn + '}');
for(var i=0, L=this.length; i < L; i++)
fn.call( this[i], data, i );
return this;
}
Array.prototype.each = each;
Exemple de utilizare:
Exemplu #1
var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]
Exemplu #2
each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');
Fiecare etichetă p se class="albastru"
Exemplu #3
each.call(document.getElementsByTagName('p'),
"if( i % 2 == 0) this.className = data;",
'red'
);
Fiecare etichetă p se class="roșu"
>
Exemplu #4
each.call(document.querySelectorAll('p.blue'),
function(newClass, i) {
if( i < 20 )
this.className = newClass;
}, 'green'
);
Și, în sfârșit, primele 20 de albastru p categorie sunt schimbat la verde
Prudență atunci când se utilizează șir de funcții: funcția este creat out-of-context și ar trebui să fie utilizate numai în cazul în care sunteți sigur de definire variabilă. În caz contrar, mai bine să treacă funcții în cazul în care de definire a domeniului evaluării este mult mai intuitiv.
Sunt câteva modalități la bucla printr-o matrice în JavaScript, ca mai jos:
pentru - l's cel mai comun. Plin bloc de cod pentru looping
var languages = ["Java", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
în timp ce - buclă în timp ce este o condiție prin. Se pare a fi cel mai rapid buclă
var text = "";
var i = 0;
while (i < 10) {
text += i + ") something<br>";
i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>
nu/în timp ce -, de asemenea, bucla printr-un bloc de cod, în timp ce condiția este adevărată, va rula cel puțin o dată
var text = ""
var i = 0;
do {
text += i + ") something <br>";
i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>
Funcțional bucle - "forEach", "harta", "filtru", de asemenea, "reduce" (acestea bucla prin funcție, dar acestea sunt utilizate în cazul în care aveți nevoie pentru a face ceva cu matrice, etc.
// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>
Pentru mai multe informații și exemple despre programare funcțională pe tablouri, uita-te la blog Funcțional programare în JavaScript: harta, se filtrează și reduce.
ECMAScript 5 (versiunea de pe JavaScript) pentru a lucra cu Tablouri:
forEach - Reiterează prin fiecare element din matrice și de a face tot ce ai nevoie cu fiecare element.
['C', 'D', 'E'].forEach(function(element, index) {
console.log(element + " is #" + (index+1) + " in the musical scale");
});
// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale
În cazul în care, mai interesat pe funcționare pe matrice folosind unele caracteristică încorporat.
harta * Se creează o nouă matrice cu rezultatul din funcția de apel invers. Această metodă este bun pentru a fi utilizate atunci când aveți nevoie pentru a formata elementele de matrice.
// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
return elem.toUpperCase();
});
// Output: ['BOB', 'JOE', 'JEN']
reducerea - după Cum spune și numele, se reduce matrice la o singură valoare de asteptare având funcția de a trece la elementul curent și rezultatul anterior de execuție.
[1,2,3,4].reduce(function(previous, current) {
return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10
*fiecare *** - Întoarce true sau false dacă toate elementele din matrice trece testul în funcție de apel invers.
// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];
ages.every(function(elem) {
return elem >= 18;
});
// Output: false
filtru - Foarte similară cu excepția faptului că fiecare filtru returnează o matrice cu elemente care returnează adevărat anumită funcție.
// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
return (elem % 2 == 0)
});
// Output: [2,4,6]
Nu's nici incorporat capacitatea de a rupe în "forEach". Pentru a întrerupe executarea folosi Matrice#unele
ca mai jos:
[1,2,3].some(function(number) {
return number === 1;
});
Acest lucru funcționează pentru că "unele" întoarce cât mai curând orice de callback, executată în array comanda, returnează true, scurt-circuit executarea de restul. Original Raspuns vezi Matrice prototip pentru unele
De asemenea, am dori să adăugați acest lucru ca pe o compoziție de o buclă inversă și un răspuns de mai sus pentru cineva care ar dori această sintaxă prea.
var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
console.log(item);
}
Pro:
Beneficiul pentru acest lucru: Aveți de referință deja în primul ca't nevoie pentru a fi declarat mai târziu cu o altă linie. Acesta este la îndemână atunci când looping prin obiectul array.
Contra:
Acest lucru va rupe de referință ori de câte ori este fals - falsey (nedefinit, etc.). Acesta poate fi folosit ca un avantaj totusi. Cu toate acestea, s-ar face un pic mai greu de citit. Și, de asemenea, în funcție de browser-ul poate fi "nu" optimizat pentru a lucra mai repede decât unul original.