Foreach js za nizove i zbirke. Kako stvoriti asocijativni niz u JavaScriptu. Eksplicitna uporaba iteratora

💖 Sviđa li vam se? Podijelite vezu sa svojim prijateljima

Definicija i primjena

JavaScript metoda za svakoga() omogućuje vam da jednom izvršite proslijeđenu funkciju za svaki element u nizu u rastućem redoslijedu indeksa.

Imajte na umu da je funkcija povratnog poziva proslijeđena kao parametar metode za svakoga() neće se pozivati ​​za izbrisane ili nedostajuće elemente niza.

Raspon elemenata obrađenih ovom metodom za svakoga() instaliran ispred prvi pozivanje funkcije povratnog poziva. Ako su elementi dodani nizu nakon njegovog poziva, tada funkcija neće biti pozvana na takve elemente.

Ako se vrijednosti postojećih elemenata niza promijene u trenutku izvođenja, tada će vrijednost proslijeđena funkciji biti vrijednost u trenutku kada je metoda za svakoga() posjećuje ih. Ako se elementi izbrišu prije nego što su posjećeni, takvi elementi neće biti posjećeni. Ako se elementi koji su već posjećeni uklone tijekom obilaska polja, kasniji elementi će biti preskočeni.

Podrška za preglednik

metoda
Opera

IExplorer

Rub
za svakoga() DaDaDaDa9.0 Da

JavaScript sintaksa:

// samo s funkcijom povratnog poziva niz.forEach(funkcija ( Trenutna vrijednost, indeks, arr)); // koristeći objekt koji se može referencirati pomoću ključne riječi this niz.forEach(funkcija ( Trenutna vrijednost, indeks, arr), thisValue);

JavaScript verzija

ECMAScript 5.1 (implementirano u JavaScriptu 1.6)

Vrijednosti parametara

ParametarOpis
funkcija Funkcija povratnog poziva koju treba izvršiti jedan puta za svaki element u nizu. Funkcija prihvaća sljedeće parametre:
  • Trenutna vrijednost - vrijednost trenutnog elementa
  • indeks - indeks polja trenutnog elementa.
  • arr - niz kojem trenutni element pripada (kroz koji se odvija prolaz).

Ako se nešto proslijedi kao parametar metodi koja nije funkcijski objekt, izbacit će se iznimka TypeError. Potreban parametar.

thisValue Objekt koji se može referencirati pomoću ključne riječi this unutar funkcije povratnog poziva. Ako je parametar thisValue se ne koristi, tada će se kao vrijednost this koristiti undefined (u konačnici to će ovisiti o normalnim pravilima konteksta izvršavanja funkcije). Izborni parametar.

Primjer upotrebe

U sljedećem primjeru ćemo pogledati kako dobiti zbroj svih elemenata niza pomoću JavaScript metoda za svakoga():

var niz =; var zbroj = 0; // inicijalizirati varijablu koja sadrži numeričku vrijednost niz.za svakoga( // proći kroz sve elemente niza funkcija sumBroj( Trenutna vrijednost) { iznos += Trenutna vrijednost; ) ); konzola .log( iznos); // prikaz vrijednosti varijable zbroja jednake 50

U sljedećem primjeru ćemo pogledati korištenje drugi argument metode za svakoga(), koji ukazuje na objekt pomoću kojeg možemo referencirati ključna riječ ovo unutar funkcije povratnog poziva:

promjenljivi brojevi = ; // inicijalizirati varijablu koja sadrži niz numeričkih vrijednosti var na kvadrat = ; // inicijalizirati varijablu koja sadrži prazan niz var myObject = ( // inicijalizirati varijablu koja sadrži objekt kvadrat:funkcija( Trenutna vrijednost) { // metoda objekta koja uzima vrijednost povratak Trenutna vrijednost * Trenutna vrijednost; // i vraća ga na kvadrat } } ; brojevima.za svakoga( // proći kroz sve elemente niza brojeva funkcija( Trenutna vrijednost) { na kvadrat.push(ovaj .kvadrat( Trenutna vrijednost)); // dodajte povratnu vrijednost kvadratne metode objekta myObject kvadratnom nizu } , mojObjekt // objekt na koji upućujemo pomoću ključne riječi this); konzola .log( na kvadrat); // prikaz vrijednosti kvadratne varijable jednake ;
  • I. Ponavljanje preko realnih nizova
    1. forEach metoda i srodne metode
    2. za petlju
    3. Ispravno korištenje for...in petlje
    4. for...of petlja (implicitna upotreba iteratora)
    5. Eksplicitna uporaba iteratora
  • II. Ponavljanje preko objekata sličnih nizu
    1. Korištenje metoda za ponavljanje stvarnih nizova
    2. Pretvori u pravi niz
    3. Napomena o objektima vremena izvođenja

I. Ponavljanje preko realnih nizova

Na ovaj trenutak Postoje tri načina za ponavljanje elemenata stvarnog niza:

  1. metoda Array.prototype.forEach ;
  2. klasična for petlja
  3. "ispravno" konstruirana for...in petlja.

Osim toga, uskoro, s dolaskom novog standarda ECMAScript 6 (ES 6), očekuju se još dvije metode:

  1. for...of petlja (implicitna upotreba iteratora);
  2. eksplicitna uporaba iteratora.

1. Metoda forEach i srodne metode

Ako je vaš projekt dizajniran da podržava značajke standarda ECMAScript 5 (ES5), možete koristiti jednu od njegovih inovacija - metodu forEach.

Primjer upotrebe:

Var a = ["a", "b", "c"]; a.forEach(funkcija(unos) ( konzola.log(unos); ));

Općenito, korištenje forEach zahtijeva povezivanje biblioteke emulacije es5-shim za preglednike koji izvorno ne podržavaju ovu metodu. To uključuje IE 8 i novije verzije rane verzije, koji su još tu i tamo u upotrebi.

Prednost forEach je u tome što nema potrebe za deklariranjem lokalnih varijabli za pohranjivanje indeksa i vrijednosti trenutnog elementa niza, jer se oni automatski prosljeđuju funkciji povratnog poziva kao argumenti.

Ako ste zabrinuti zbog mogućih troškova povratnog poziva za svaki element, ne brinite i pročitajte ovo.

forEach je dizajniran za iteraciju kroz sve elemente niza, ali osim njega, ES5 nudi još nekoliko korisnih metoda za iteraciju kroz sve ili neke elemente plus izvođenje nekih radnji na njima:

  • svaki - vraća istinito ako za svaki element niza povratni poziv vraća vrijednost koja se može pretvoriti u istinito .
  • some - vraća true ako za barem jedan element niza povratni poziv vraća vrijednost koja se može pretvoriti u true.
  • filter - stvara novi niz koji uključuje one elemente izvornog niza za koje povratni poziv vraća true.
  • map - stvara novi niz koji se sastoji od vrijednosti vraćenih povratnim pozivom.
  • smanji - reducira niz na jednu vrijednost, primjenjujući povratni poziv na svaki element niza redom, počevši od prvog (može biti korisno za izračun zbroja elemenata niza i druge funkcije sažetka).
  • reduceRight - radi slično kao reduce, ali ponavlja elemente obrnutim redoslijedom.

2. Za petlju

Dobro staro za pravila:

Var a = ["a", "b", "c"]; var indeks; za (indeks = 0; indeks< a.length; ++index) { console.log(a); }

Ako je duljina niza konstantna tijekom cijele petlje, a sama petlja pripada odjeljku koda koji je kritičan za performanse (što je malo vjerojatno), tada možete upotrijebiti "optimalniju" verziju for koja pohranjuje duljinu niza :

Var a = ["a", "b", "c"]; var indeks, len; za (indeks = 0, dužina = a.duljina; indeks< len; ++index) { console.log(a); }

U teoriji, ovaj kod bi trebao raditi malo brže od prethodnog.

Ako redoslijed elemenata nije bitan, onda možete ići i dalje u smislu optimizacije i riješiti se varijable za pohranjivanje duljine niza, mijenjajući redoslijed pretraživanja obrnutim:

Var a = ["a", "b", "c"]; var indeks; za (index = a.length - 1; index >= 0; --index) ( console.log(a); )

Međutim, u modernim JavaScript motorima takve igre optimizacije obično ne znače ništa.

3. Ispravna uporaba petlje for...in

Ako vam se savjetuje da koristite for...in petlju, zapamtite da ponavljanje nizova nije ono za što je namijenjeno. Suprotno uobičajenom pogrešnom shvaćanju, petlja for...in ne ponavlja preko indeksa polja, već radije kroz nabrojiva svojstva objekta.

Međutim, u nekim slučajevima, kao što je ponavljanje preko rijetkih nizova, for...in može biti korisno, sve dok poduzmete mjere opreza, kao što je prikazano u primjeru ispod:

// a - rijetki niz var a = ; a = "a"; a = "b"; a = "c"; for (var ključ u a) ( if (a.hasOwnProperty(ključ) && /^0$|^d*$/.test(ključ) && ključ<= 4294967294) { console.log(a); } }

U ovom primjeru, dvije provjere se izvode pri svakoj iteraciji petlje:

  1. da niz ima vlastito svojstvo koje se zove ključ (nije naslijeđeno od svog prototipa).
  2. taj ključ je niz koji sadrži decimalni prikaz cijelog broja čija je vrijednost manja od 4294967294. Odakle dolazi zadnji broj? Iz definicije indeksa niza u ES5, koja pokazuje da je najveći indeks koji element u nizu može imati: (2^32 - 2) = 4294967294 .

Naravno, takve će provjere oduzeti nepotrebno vrijeme prilikom izvođenja petlje. Ali u slučaju rijetkog niza, ova metoda je učinkovitija od for petlje, budući da se u ovom slučaju ponavljaju samo oni elementi koji su eksplicitno definirani u nizu. Dakle, u gornjem primjeru, izvršit će se samo 3 iteracije (za indekse 0, 10 i 10000) - naspram 10001 u for petlji.

Kako ne biste pisali tako glomazan kontrolni kod svaki put kada trebate iterirati kroz niz, možete ga napisati kao zasebnu funkciju:

Funkcija arrayHasOwnIndex(niz, ključ) ( return array.hasOwnProperty(ključ) && /^0$|^d*$/.test(ključ) && ključ<= 4294967294; }

Tada će tijelo petlje iz primjera biti značajno smanjeno:

Za (unesite a) ( if (arrayHasOwnIndex(a, ključ)) ( console.log(a); ) )

Gore razmotreni kontrolni kod je univerzalan, prikladan za sve slučajeve. No umjesto toga možete koristiti kraću verziju, iako formalno ne sasvim ispravnu, ali ipak prikladnu za većinu slučajeva:

Za (unesite a) ( if (a.hasOwnProperty(key) && String(parseInt(key, 10)) === ključ) ( console.log(a); ) )

4. For...of petlja (implicitna upotreba iteratora)

ES6, još uvijek u statusu nacrta, trebao bi uvesti iteratore u JavaScript.

Iterator je protokol koji implementira objekt koji definira standardni način za dobivanje niza vrijednosti (konačnih ili beskonačnih).
Objekt ima iterator ako definira next() metodu, funkciju bez argumenata koja vraća objekt s dva svojstva:

  1. gotovo (boolean) - istinito ako je iterator došao do kraja niza koji se može ponoviti. Inače je vrijednost lažna.
  2. vrijednost - definira vrijednost koju vraća iterator. Može biti nedefinirano (nedostaje) ako je svojstvo done istinito.

Mnogi ugrađeni objekti, uklj. pravi nizovi imaju iteratore prema zadanim postavkama. Najjednostavniji način korištenja iteratora na stvarnim nizovima je korištenje konstrukcije new for...of.

Primjer korištenja za...od:

Varval; var a = ["a", "b", "c"]; za (val od a) ( console.log(val); )

U gornjem primjeru, for...of petlja implicitno poziva iterator objekta Array da dobije svaku vrijednost niza.

5. Eksplicitna uporaba iteratora

Iteratori se također mogu koristiti eksplicitno, međutim, u ovom slučaju kod postaje mnogo kompliciraniji u usporedbi s for...of petljom. Izgleda otprilike ovako:

Var a = ["a", "b", "c"]; unos var; dok (!(entry = a.next()).done) ( console.log(entry.value); )

II. Ponavljanje preko objekata sličnih nizu

Osim pravih nizova, u JavaScriptu postoje i objekti nalik na niz . Ono što im je zajedničko sa stvarnim nizovima je da imaju svojstvo duljine i svojstva imenovana kao brojevi koji odgovaraju elementima niza. Primjeri uključuju DOM kolekcije NodeList i pseudoniz argumenata, dostupan unutar bilo koje funkcije/metode.

1. Korištenje metoda za ponavljanje stvarnih nizova

U najmanju ruku, većina, ako ne i sve, metode iteracije preko stvarnih nizova mogu se koristiti za iteraciju preko objekata sličnih nizovima.

For i for...in konstrukcije mogu se primijeniti na objekte slične nizovima na potpuno isti način kao što se primjenjuju na stvarne nizove.

forEach i druge metode Array.prototype također se primjenjuju na objekte slične nizu. Da biste to učinili, morate koristiti Function.call ili Function.apply.

Na primjer, ako želite primijeniti forEach na svojstvo childNodes objekta Node, učinili biste to ovako:

Array.prototype.forEach.call(node.childNodes, function(child) ( // učiniti nešto s objektom dijete));

Kako bi ovaj trik bio lakši za ponovno korištenje, možete deklarirati referencu na metodu Array.prototype.forEach u zasebnoj varijabli i koristiti je kao prečac:

// (pod pretpostavkom da je sav kod ispod u istom opsegu) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // učiniti nešto s objektom dijete));

Ako objekt sličan nizu ima iterator, on se može koristiti eksplicitno ili implicitno za iteraciju preko objekta na isti način kao za stvarne nizove.

2. Pretvorite u pravi niz

Također postoji još jedan, vrlo jednostavan način za iteraciju preko objekta nalik nizu: pretvorite ga u pravi niz i koristite bilo koju od gore spomenutih metoda za iteraciju preko stvarnih nizova. Za pretvorbu možete koristiti generičku metodu Array.prototype.slice koja se može primijeniti na bilo koji objekt sličan nizu. To se radi vrlo jednostavno, kao što je prikazano u primjeru u nastavku:

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

Na primjer, ako želite konvertirati kolekciju NodeList u stvarni niz, trebao bi vam kod otprilike ovaj:

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

3. Napomena o objektima vremena izvođenja

Ako primijenite Array.prototype metode na runtime objekte (kao što su DOM kolekcije), tada trebate biti svjesni da nije zajamčeno da će ove metode ispravno raditi u svim runtime okruženjima (uključujući preglednike). To ovisi o ponašanju određenog objekta u određenom izvršnom okruženju, ili točnije, o tome kako je apstraktna operacija HasProperty implementirana u ovom objektu. Problem je u tome što sam standard ES5 dopušta mogućnost da se objekt loše ponaša s obzirom na ovu operaciju (vidi §8.6.2).

Stoga je važno testirati rad metoda Array.prototype u svakom runtime okruženju (pregledniku) u kojem planirate koristiti svoju aplikaciju.

  • I. Ponavljanje preko realnih nizova
    1. forEach metoda i srodne metode
    2. za petlju
    3. Ispravno korištenje for...in petlje
    4. for...of petlja (implicitna upotreba iteratora)
    5. Eksplicitna uporaba iteratora
    1. Korištenje metoda za ponavljanje stvarnih nizova
    2. Pretvori u pravi niz
    3. Napomena o objektima vremena izvođenja

I. Ponavljanje preko realnih nizova

Trenutačno postoje tri načina za ponavljanje elemenata stvarnog niza:
  1. metoda Array.prototype.forEach ;
  2. klasična for petlja
  3. "ispravno" konstruirana for...in petlja.
Osim toga, uskoro, s dolaskom novog standarda ECMAScript 6 (ES 6), očekuju se još dvije metode:
  1. for...of petlja (implicitna upotreba iteratora);
  2. eksplicitna uporaba iteratora.

1. Metoda forEach i srodne metode

Ako je vaš projekt dizajniran da podržava značajke standarda ECMAScript 5 (ES5), možete koristiti jednu od njegovih inovacija - metodu forEach.

Primjer upotrebe:
var a = ["a", "b", "c"]; a.forEach(funkcija(unos) ( konzola.log(unos); ));
Općenito, korištenje forEach zahtijeva povezivanje biblioteke emulacije es5-shim za preglednike koji izvorno ne podržavaju ovu metodu. To uključuje IE 8 i ranije, koji se još uvijek koriste na nekim mjestima.

Prednost forEach je u tome što nema potrebe za deklariranjem lokalnih varijabli za pohranjivanje indeksa i vrijednosti trenutnog elementa niza, jer se oni automatski prosljeđuju funkciji povratnog poziva kao argumenti.

Ako ste zabrinuti zbog mogućih troškova povratnog poziva za svaki element, ne brinite i pročitajte ovo.

ForEach je dizajniran za iteraciju kroz sve elemente niza, ali osim toga, ES5 nudi još nekoliko korisnih metoda za iteraciju kroz sve ili neke elemente plus izvođenje nekih radnji na njima:

  • svaki - vraća istinito ako za svaki element niza povratni poziv vraća vrijednost koja se može pretvoriti u istinito .
  • some - vraća true ako za barem jedan element niza povratni poziv vraća vrijednost koja se može pretvoriti u true.
  • filter - stvara novi niz koji uključuje one elemente izvornog niza za koje povratni poziv vraća true.
  • map - stvara novi niz koji se sastoji od vrijednosti vraćenih povratnim pozivom.
  • smanji - reducira niz na jednu vrijednost, primjenjujući povratni poziv na svaki element niza redom, počevši od prvog (može biti korisno za izračun zbroja elemenata niza i druge funkcije sažetka).
  • reduceRight - radi slično kao reduce, ali ponavlja elemente obrnutim redoslijedom.

2. Za petlju

Dobro staro za pravila:

Var a = ["a", "b", "c"]; var indeks; za (indeks = 0; indeks< a.length; ++index) { console.log(a); }
Ako je duljina niza konstantna tijekom cijele petlje, a sama petlja pripada odjeljku koda koji je kritičan za performanse (što je malo vjerojatno), tada možete upotrijebiti "optimalniju" verziju for koja pohranjuje duljinu niza :

Var a = ["a", "b", "c"]; var indeks, len; za (indeks = 0, dužina = a.duljina; indeks< len; ++index) { console.log(a); }
U teoriji, ovaj kod bi trebao raditi malo brže od prethodnog.

Ako redoslijed elemenata nije bitan, onda možete ići i dalje u smislu optimizacije i riješiti se varijable za pohranjivanje duljine niza, mijenjajući redoslijed pretraživanja obrnutim:

Var a = ["a", "b", "c"]; var indeks; za (index = a.length - 1; index >= 0; --index) ( console.log(a); )
Međutim, u modernim JavaScript motorima takve igre optimizacije obično ne znače ništa.

3. Ispravna uporaba petlje for...in

Ako vam se savjetuje da koristite for...in petlju, zapamtite da ponavljanje nizova nije ono za što je namijenjeno. Suprotno uobičajenom pogrešnom shvaćanju, petlja for...in ne ponavlja preko indeksa polja, već radije kroz nabrojiva svojstva objekta.

Međutim, u nekim slučajevima, kao što je ponavljanje preko rijetkih nizova, for...in može biti korisno, sve dok poduzmete mjere opreza, kao što je prikazano u primjeru ispod:

// a - rijetki niz var a = ; a = "a"; a = "b"; a = "c"; for (var ključ u a) ( if (a.hasOwnProperty(ključ) && /^0$|^\d*$/.test(ključ) && ključ<= 4294967294) { console.log(a); } }
U ovom primjeru, dvije provjere se izvode pri svakoj iteraciji petlje:

  1. da niz ima vlastito svojstvo koje se zove ključ (nije naslijeđeno od svog prototipa).
  2. taj ključ je niz koji sadrži decimalni prikaz cijelog broja čija je vrijednost manja od 4294967294. Odakle dolazi zadnji broj? Iz definicije indeksa niza u ES5, koja pokazuje da je najveći indeks koji element u nizu može imati: (2^32 - 2) = 4294967294 .
Naravno, takve će provjere oduzeti nepotrebno vrijeme prilikom izvođenja petlje. Ali u slučaju rijetkog niza, ova metoda je učinkovitija od for petlje, jer se u ovom slučaju ponavljaju samo oni elementi koji su eksplicitno definirani u nizu. Dakle, u gornjem primjeru, izvršit će se samo 3 iteracije (za indekse 0, 10 i 10000) - naspram 10001 u for petlji.

Kako ne biste pisali tako glomazan kontrolni kod svaki put kada trebate iterirati kroz niz, možete ga napisati kao zasebnu funkciju:

Funkcija arrayHasOwnIndex(niz, ključ) ( return array.hasOwnProperty(ključ) && /^0$|^\d*$/.test(ključ) && ključ<= 4294967294; }
Tada će tijelo petlje iz primjera biti značajno smanjeno:

Za (unesite a) ( if (arrayHasOwnIndex(a, ključ)) ( console.log(a); ) )
Gore razmotreni kontrolni kod je univerzalan, prikladan za sve slučajeve. No umjesto toga možete koristiti kraću verziju, iako formalno ne sasvim ispravnu, ali ipak prikladnu za većinu slučajeva:

Za (unesite a) ( if (a.hasOwnProperty(key) && String(parseInt(key, 10)) === ključ) ( console.log(a); ) )

4. For...of petlja (implicitna upotreba iteratora)

ES6, još uvijek u statusu nacrta, trebao bi uvesti iteratore u JavaScript.

Iterator je protokol koji implementira objekt koji definira standardni način za dobivanje niza vrijednosti (konačnih ili beskonačnih).
Iterator je objekt koji definira next() metodu - funkciju bez argumenata koja vraća objekt s dva svojstva:

  1. gotovo (boolean) - istinito ako je iterator došao do kraja niza koji se može ponoviti. Inače je vrijednost lažna.
  2. vrijednost - definira vrijednost koju vraća iterator. Može biti nedefinirano (nedostaje) ako je svojstvo done istinito.
Mnogi ugrađeni objekti, uklj. pravi nizovi imaju iteratore prema zadanim postavkama. Najjednostavniji način korištenja iteratora na stvarnim nizovima je korištenje konstrukcije new for...of.

Primjer korištenja za...od:

Varval; var a = ["a", "b", "c"]; za (val od a) ( console.log(val); )
U gornjem primjeru, for...of petlja implicitno poziva iterator objekta Array da dobije svaku vrijednost niza.

5. Eksplicitna uporaba iteratora

Iteratori se također mogu koristiti eksplicitno, međutim, u ovom slučaju kod postaje mnogo kompliciraniji u usporedbi s for...of petljom. Izgleda otprilike ovako:

Var a = ["a", "b", "c"]; var it = a.entries(); unos var; while (!(entry = it.next()).done) ( console.log(entry.value); )
U ovom primjeru, metoda Array.prototype.entries vraća iterator koji se koristi za prikaz vrijednosti niza. U svakoj iteraciji, entry.value sadrži polje u obliku [ključ, vrijednost] .

II. Ponavljanje preko objekata sličnih nizu

Osim pravih nizova, u JavaScriptu postoje i objekti nalik na niz . Ono što im je zajedničko sa stvarnim nizovima je da imaju svojstvo duljine i svojstva imenovana kao brojevi koji odgovaraju elementima niza. Primjeri uključuju DOM kolekcije NodeList i pseudoniz argumenata, dostupan unutar bilo koje funkcije/metode.

1. Korištenje metoda za ponavljanje stvarnih nizova

U najmanju ruku, većina, ako ne i sve, metode iteracije preko stvarnih nizova mogu se koristiti za iteraciju preko objekata sličnih nizovima.

For i for...in konstrukcije mogu se primijeniti na objekte slične nizovima na potpuno isti način kao što se primjenjuju na stvarne nizove.

ForEach i druge metode Array.prototype također se primjenjuju na objekte slične nizu. Da biste to učinili, morate koristiti Function.call ili Function.apply.

Na primjer, ako želite primijeniti forEach na svojstvo childNodes objekta Node, učinili biste to ovako:

Array.prototype.forEach.call(node.childNodes, function(child) ( // učiniti nešto s objektom dijete));
Kako bi ovaj trik bio lakši za ponovno korištenje, možete deklarirati referencu na metodu Array.prototype.forEach u zasebnoj varijabli i koristiti je kao prečac:

// (pod pretpostavkom da je sav kod ispod u istom opsegu) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // učiniti nešto s objektom dijete));
Ako objekt sličan nizu ima iterator, on se može koristiti eksplicitno ili implicitno za iteraciju preko objekta na isti način kao za stvarne nizove.

2. Pretvorite u pravi niz

Također postoji još jedan, vrlo jednostavan način za iteraciju preko objekta nalik nizu: pretvorite ga u pravi niz i koristite bilo koju od gore spomenutih metoda za iteraciju preko stvarnih nizova. Za pretvorbu možete koristiti generičku metodu Array.prototype.slice koja se može primijeniti na bilo koji objekt sličan nizu. To se radi vrlo jednostavno, kao što je prikazano u primjeru u nastavku:

Var trueArray = Array.prototype.slice.call(arrayLikeObject, 0);
Na primjer, ako želite konvertirati kolekciju NodeList u stvarni niz, trebao bi vam kod otprilike ovaj:

Var divs = Array.prototype.slice.call(document.querySelectorAll("div"), 0);
Ažuriraj: Kao što su primijetili u komentarima rock i torbasow, u ES6 možete koristiti vizualniju metodu Array.from umjesto Array.prototype.slice.

3. Napomena o objektima vremena izvođenja

Ako primijenite Array.prototype metode na runtime objekte (kao što su DOM kolekcije), tada trebate biti svjesni da nije zajamčeno da će ove metode ispravno raditi u svim runtime okruženjima (uključujući preglednike). To ovisi o ponašanju određenog objekta u određenom izvršnom okruženju, ili točnije, o tome kako je apstraktna operacija HasProperty implementirana u ovom objektu. Problem je u tome što sam standard ES5 dopušta mogućnost da se objekt loše ponaša s obzirom na ovu operaciju (vidi §8.6.2).

Stoga je važno testirati rad metoda Array.prototype u svakom runtime okruženju (pregledniku) u kojem planirate koristiti svoju aplikaciju.

The za svakoga() metoda izvršava danu funkciju jednom za svaki element niza.

Izvor za ovaj interaktivni primjer pohranjen je u GitHub repozitorij. Ako želite doprinijeti projektu interaktivnih primjera, klonirajte https://github.com/mdn/interactive-examples i pošaljite nam zahtjev za povlačenje.

Sintaksa

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

Parametri

povratni poziv Funkcija koja se izvršava na svakom elementu. Prihvaća između jednog i tri argumenta: currentValue Trenutni element koji se obrađuje u nizu. index Opcijski Indeks currentValue u nizu. array Optional Pozvan je array forEach(). thisArg Izborna vrijednost koja se koristi kao this prilikom izvršavanja povratnog poziva.

Povratna vrijednost

Opis

forEach() poziva dostavljenu funkciju povratnog poziva jednom za svaki element u nizu uzlaznim redoslijedom. Ne poziva se za svojstva indeksa koja su izbrisana ili nisu inicijalizirana. (Za rijetke nizove, .)

povratni poziv se poziva s tri argumenta:

  1. vrijednost elementa
  2. indeks elementa
  3. objekt Array koji se prelazi

Ako je thisArg parametar dostavljen za forEach(), on će se koristiti kao povratni poziv ove vrijednosti. ThisArg vrijednost je u konačnici vidljiva povratnim pozivom i određuje se prema uobičajenim pravilima za određivanje this koje vidi funkcija.

Raspon elemenata koje obrađuje forEach() postavlja se prije prvog poziva povratnog poziva. Elementi koji se pridodaju nizu nakon početka poziva za forEach() neće biti posjećeni povratnim pozivom. Ako se postojeći elementi niza promijene ili izbrišu, njihova vrijednost proslijeđena povratnom pozivu bit će vrijednost u trenutku kada ih forEach() posjeti; elementi koji su izbrisani prije posjeta se ne posjećuju. Ako se elementi koji su već posjećeni uklone (npr. korištenjem shift()) tijekom iteracije, kasniji elementi bit će preskočeni. (Pogledajte ovaj primjer u nastavku.)

forEach() izvršava funkciju povratnog poziva jednom za svaki element niza; za razliku od map() ili reduce() uvijek vraća vrijednost nedefiniranu i ne može se ulančati. Tipičan slučaj upotrebe je izvršavanje nuspojava na kraju lanca.

forEach() ne mijenja niz na kojem je pozvan. (Međutim, povratni poziv to može učiniti)

Ne postoji način da se zaustavi ili prekine forEach() petlja osim izbacivanjem iznimke. Ako vam je potrebno takvo ponašanje, metoda forEach() je pogrešan alat.

Prijevremeni raskid može se postići sa:

Metode niza: every(), some(), find() i findIndex() testiraju elemente niza s predikatom koji vraća istinitu vrijednost kako bi se utvrdilo je li potrebno daljnje ponavljanje.

Primjeri

Nema operacije za neinicijalizirane vrijednosti (rijetki nizovi)

const arraySparse = let numCallbackRuns = 0 arraySparse.forEach(function(element)( console.log(element) numCallbackRuns++ )) console.log("numCallbackRuns: ", numCallbackRuns) // 1 // 3 // 7 // numCallbackRuns: 3 // komentar: kao što vidite vrijednost koja nedostaje između 3 i 7 nije pozvala funkciju povratnog poziva.

Pretvaranje for petlje u forEach

const items = ["item1", "item2", "item3"] const copy = // prije za (neka i = 0; i< items.length; i++) { copy.push(items[i]) } // after items.forEach(function(item){ copy.push(item) })

Ispis sadržaja niza

Bilješka: Kako biste prikazali sadržaj niza u konzoli, možete koristiti console.table() , koji ispisuje formatiranu verziju niza.

Sljedeći primjer ilustrira alternativni pristup, koristeći forEach() .

Sljedeći kod bilježi redak za svaki element u nizu:

Function logArrayElements(element, index, array) ( console.log("a[" + index + "] = " + element) ) // Primijetite da je indeks 2 preskočen, budući da nema stavke na // toj poziciji u niz... .zaSvaki(logArrayElements) // zapisnici: // a = 2 // a = 5 // a = 9

Koristeći thisArg

Sljedeći (izmišljeni) primjer ažurira svojstva objekta iz svakog unosa u nizu:

Funkcija Counter() ( this.sum = 0 this.count = 0 ) Counter.prototype.add = function(array) ( array.forEach(function(entry) ( this.sum += entry ++this.count ), this ) // ^---- Napomena ) const obj = new Counter() obj.add() obj.count // 3 obj.sum // 16

Budući da je thisArg parametar (this) dostavljen forEach() , prosljeđuje se povratnom pozivu svaki put kada se pozove. Povratni poziv ga koristi kao svoju this vrijednost.

Funkcija kopiranja objekta

Sljedeći kod stvara kopiju zadanog objekta.

Postoje različiti načini za stvaranje kopije objekta. Sljedeće je samo jedan način i predstavljeno je kako bi se objasnilo kako Array.prototype.forEach() radi pomoću ECMAScript 5 Object.* funkcija meta svojstava.

Funkcija copy(obj) ( const copy = Object.create(Object.getPrototypeOf(obj)) const propNames = Object.getOwnPropertyNames(obj) propNames.forEach(function(name) ( const desc = Object.getOwnPropertyDescriptor(obj, name) Object .defineProperty(copy, name, desc) )) return copy ) const obj1 = ( a: 1, b: 2 ) const obj2 = copy(obj1) // obj2 sada izgleda kao obj1

Ako se polje modificira tijekom iteracije, drugi elementi mogu biti preskočeni.

Sljedeći primjer bilježi "jedan", "dva", "četiri".

Kada unos koji sadrži vrijednost "two" 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() ne radi kopiju niza prije ponavljanja.

Neka riječi = ["jedan", "dva", "tri", "četiri"] words.forEach(function(word) ( console.log(word) if (word === "two") ( words.shift( ) ) )) // jedan // dva // četiri

Spljoštiti niz

Sljedeći primjer je ovdje samo u svrhu učenja. Ako želite spljoštiti niz pomoću ugrađenih metoda, možete koristiti Array.prototype.flat() (za koji se očekuje da će biti dio ES2019 i već je implementiran u nekim preglednicima).

/** * Sravnjuje proslijeđeni niz u jednodimenzionalnom nizu * * @params (niz) arr * @povratak (niz) */ function flatten(arr) ( const result = arr.forEach((i) => ( if (Niz. isArray(i)) ( result.push(...flatten(i)) ) else ( result.push(i) )) return result ) // Upotreba const problem = , 8, 9]] izravnaj(problem) / /

Napomena o korištenju obećanja ili asinkronih funkcija

let ratings = neka sum = 0 let sumFunction = async funkcija (a, b) ( return a + b ) ratings.forEach(async function(rating) ( sum = await sumFunction(sum, rating) )) console.log(sum) // Očekivani izlaz: 14 // Stvarni izlaz: 0

Tehnički podaci

Specifikacija Status Komentar
ECMAScript najnoviji nacrt (ECMA-262)
Nacrt
ECMAScript 2015 (6. izdanje, ECMA-262)
Definicija "Array.prototype.forEach" u toj specifikaciji.
Standard
ECMAScript 5.1 (ECMA-262)
Definicija "Array.prototype.forEach" u toj specifikaciji.
Standard Početna definicija. Implementirano u JavaScriptu 1.6.

Kompatibilnost preglednika

Tablica kompatibilnosti na ovoj stranici generirana je iz strukturiranih podataka. Ako želite doprinijeti podacima, pogledajte https://github.com/mdn/browser-compat-data i pošaljite nam zahtjev za povlačenje.

Ažurirajte podatke o kompatibilnosti na GitHubu

Radna površinaMobilniposlužitelj
KromRubFirefoxInternet ExplorerOperaSafariAndroid web-prikazChrome za AndroidFirefox za AndroidOpera za AndroidSafari na iOS-uSamsung InternetNode.js
za svakogaPuna podrška za Chrome 1Edge Potpuna podrška 12Firefox Puna podrška 1.5IE puna podrška 9Opera Potpuna podrška DaSafari puna podrška 3WebView Android Puna podrška ≤37Chrome Android Puna podrška 18Firefox Android Puna podrška 4Opera Android Puna podrška DaSafari iOS Potpuna podrška 1Samsung Internet Android Puna podrška 1.0nodejs Puna podrška Da

Zadnja izmjena: 26.03.2018

Objekt Array predstavlja niz i pruža niz svojstava i metoda pomoću kojih možemo manipulirati nizom.

Inicijalizacija niza

Prazan niz možete stvoriti uglatim zagradama ili konstruktorom polja:

Var korisnici = novi niz(); var ljudi = ; console.log(korisnici); // Array console.log(people); //Niz

Možete odmah inicijalizirati niz s određenim brojem elemenata:

Var users = new Array("Tom", "Bill", "Alice"); var ljudi = ["Sam", "John", "Kate"]; console.log(korisnici); // ["Tom", "Bill", "Alice"] console.log(ljudi); // ["Sam", "John", "Kate"]

Možete definirati niz i dodavati mu nove elemente dok idete:

Var korisnici = novi niz(); korisnici = "Tom"; korisnici = "Kate"; console.log(korisnici); // "Tom" console.log(users); // nedefiniran

Nije važno što je prema zadanim postavkama niz kreiran s nultom duljinom. Koristeći indekse, možemo zamijeniti jedan ili drugi element u nizu na određeni indeks.

duljina

Da biste saznali duljinu niza, upotrijebite svojstvo length:

Var fruit = new Array(); voće = "jabuke"; voće = "kruške"; voće = "šljive"; document.write("U polju fruit " + fruit.length + " element:
"); for(var i=0; i< fruit.length; i++) document.write(fruit[i] + "
");

Zapravo, duljina niza bit će indeks posljednjeg elementa plus jedan. Na primjer:

Var korisnici = novi niz(); // postoji 0 elemenata u nizu korisnici = "Tom"; korisnici = "Kate"; korisnici = "Sam"; za (var i=0; i

Ispis preglednika:

Tom Kate nedefinirano nedefinirano Sam

Unatoč tome što nismo dodali elemente za indekse 2 i 3, duljina niza će u ovom slučaju biti broj 5. Samo što će elementi s indeksima 2 i 3 imati vrijednost nedefinirano.

Kopiranje niza. kriška()

Kopiranje niza može biti plitko ili plitko (shallow copy) i duboko (deep copy).

Za plitko kopiranje dovoljno je varijabli dodijeliti vrijednost druge varijable koja pohranjuje niz:

Var korisnici = ["Tom", "Sam", "Bill"]; console.log(korisnici); // ["Tom", "Sam", "Bill"] var ljudi = korisnici; // plitko kopiranje ljudi = "Mike"; // promijenimo drugi element console.log(users); // ["Tom", "Mike", "Bill"]

U ovom slučaju, varijabla people, nakon kopiranja, pokazivat će na isti niz kao varijabla users. Stoga, kada se mijenjaju elementi u ljudima, mijenjat će se i elementi u korisnicima, budući da se zapravo radi o istom nizu.

Ovo ponašanje nije uvijek poželjno. Na primjer, želimo da varijable pokazuju na zasebne nizove nakon kopiranja. I u ovom slučaju, možete koristiti duboko kopiranje pomoću metode slice():

Var korisnici = ["Tom", "Sam", "Bill"]; console.log(korisnici); // ["Tom", "Sam", "Bill"] var ljudi = korisnici.slice(); // duboka kopija ljudi = "Mike"; // promijenimo drugi element console.log(users); // ["Tom", "Sam", "Bill"] console.log(ljudi); // ["Tom", "Mike", "Bill"]

U ovom slučaju, nakon kopiranja, varijable će upućivati ​​na različite nizove, a možemo ih mijenjati odvojeno jedne od drugih.

Metoda slice() također vam omogućuje kopiranje dijela niza:

Var korisnici = ["Tom", "Sam", "Bill", "Alice", "Kate"]; var ljudi = korisnici.slice(1, 4); konzola.log(ljudi); // ["Sam", "Bill", "Alice"]

Metodi slice() prosljeđuju se početni i završni indeksi, koji se koriste za dohvaćanje vrijednosti iz niza. To jest, u ovom slučaju odabir u novi niz ide od indeksa 1 do indeksa 4, ne uključujući. A budući da indeksiranje niza počinje od nule, novi niz će sadržavati drugi, treći i četvrti element.

gurnuti()

Metoda push() dodaje element na kraj niza:

Var voće = ; voće.push("jabuke"); voće.push("kruške"); voće.push("šljive"); voće.push("trešnja","marelica
"); document.write(voće); // jabuke, kruške, šljive, trešnje, marelice

pop()

Metoda pop() uklanja posljednji element iz niza:

Var voće = ["jabuke", "kruške", "šljive"]; var lastFruit = fruit.pop(); // izdvajanje zadnjeg elementa iz polja document.write(lastFruit + "
"); document.write("U polju fruit " + fruit.length + " element:
"); for(var i=0; i ");

Ispis preglednika:

Šljive Voćni niz ima 2 elementa: jabuke kruške

pomak()

Metoda shift() dohvaća i uklanja prvi element iz niza:

Var voće = ["jabuke", "kruške", "šljive"]; var firstFruit = fruit.shift(); document.write(firstFruit + "
"); document.write("U polju fruit " + fruit.length + " element:
"); for(var i=0; i ");

Ispis preglednika:

Jabuke Voćni niz ima 2 elementa: kruške šljive

poništi pomak()

Metoda unshift() dodaje novi element na početak niza:

Var voće = ["jabuke", "kruške", "šljive"]; voće.unshift("marelice"); dokument.pisati(voće);

Ispis preglednika:

Marelice, jabuke, kruške, šljive

Uklanjanje elementa prema indeksu. spoj()

Metoda splice() uklanja elemente na određenom indeksu. Na primjer, uklanjanje elemenata iz trećeg indeksa:

Var korisnici = ["Tom", "Sam", "Bill", "Alice", "Kate"]; var deleted = korisnici.splice(3); console.log(izbrisano); // [ "Alice", "Kate" ] console.log(users); // [ "Tom", "Sam", "Bill" ]

Metoda slice vraća uklonjene elemente.

U ovom slučaju, brisanje se događa od početka niza. Ako proslijedite negativan indeks, tada će se brisanje izvršiti s kraja niza. Na primjer, uklonimo zadnji element:

Var korisnici = ["Tom", "Sam", "Bill", "Alice", "Kate"]; var deleted = korisnici.splice(-1); console.log(izbrisano); // [ "Kate" ] console.log(users); // [ "Tom", "Sam", "Bill", "Alice" ]

Dodatna verzija metode omogućuje vam da odredite završni indeks za brisanje. Na primjer, izbrišite prvi do treći indeks:

Var korisnici = ["Tom", "Sam", "Bill", "Alice", "Kate"]; var deleted = korisnici.splice(1,3); console.log(izbrisano); // [ "Sam", "Bill", "Alice" ] console.log(users); // [ "Tom", "Kate" ]

Druga verzija metode spajanja omogućuje umetanje novih elemenata umjesto izbrisanih elemenata:

Var korisnici = ["Tom", "Sam", "Bill", "Alice", "Kate"]; var deleted = users.splice(1,3, "Ann", "Bob"); console.log(izbrisano); // [ "Sam", "Bill", "Alice" ] console.log(users); // [ "Tom", "Ann", "Bob", "Kate" ]

U ovom slučaju brišemo tri elementa od 1. do 3. indeksa i umjesto njih umećemo dva elementa.

concat()

Metoda concat() koristi se za kombiniranje nizova:

Var voće = ["jabuke", "kruške", "šljive"]; var povrće = ["rajčice", "krastavci", "krumpir"]; var proizvodi = voće.concat(povrće); za (var i=0; i< products.length; i++) document.write(products[i] + "
");

U ovom slučaju nije potrebno kombinirati samo nizove istog tipa. Moguće su različite vrste:

Var voće = ["jabuke", "kruške", "šljive"]; var cijene = ; var proizvodi = voće.concat(cijene);

pridružiti()

Metoda join() spaja sve elemente niza u jedan niz:

Var voće = ["jabuke", "kruške", "šljive", "marelice", "breskve"]; var fruitString = fruit.join(", "); document.write(fruitString);

Metodi join() prosljeđuje se razdjelnik između elemenata niza. U ovom slučaju, zarez i razmak (", ") koristit će se kao razdjelnik.

vrsta()

Metoda sort() sortira niz uzlaznim redoslijedom:

Var voće = ["jabuke", "kruške", "šljive", "marelice", "breskve"]; voće.sort(); za (var i=0; i< fruit.length; i++) document.write(fruit[i] + "
");

Ispis preglednika:

Marelice kruške breskve šljive jabuke

obrnuti ()

Metoda reverse() preokreće niz unatrag:

Var voće = ["jabuke", "kruške", "šljive", "marelice", "breskve"]; fruit.reverse(); za (var i=0; i< fruit.length; i++) document.write(fruit[i] + "
");

Ispis preglednika:

Breskve marelice šljive kruške jabuke

U kombinaciji s metodom sort(), možete sortirati niz silaznim redoslijedom:

Var voće = ["jabuke", "kruške", "šljive", "marelice", "breskve"]; fruit.sort().reverse(); za (var i=0; i< fruit.length; i++) document.write(fruit[i] + "
");

Ispis preglednika:

Jabuke šljive breskve kruške marelice

Pronalaženje indeksa elementa

Metode indexOf() i lastIndexOf() vraćaju indeks prvog i zadnjeg uključivanja elementa u polje. Na primjer:

Var voće = ["jabuke", "kruške", "šljive", "jabuke", "kruške"]; var firstIndex = fruit.indexOf("jabuke"); var lastIndex = fruit.lastIndexOf("jabuke"); var otherIndex = fruit.indexOf("trešnje"); document.write(firstIndex); // 0 document.write(lastIndex); // 3 document.write(otherIndex); // -1

firstIndex ima vrijednost 0 jer je prvo uključivanje retka "jabuke" u nizu na indeksu 0, a posljednje na indeksu 3.

Ako element nije u nizu, tada u ovom slučaju metode indexOf() i lastIndexOf() vraćaju vrijednost -1.

svaki()

Metoda every() provjerava odgovaraju li svi elementi određenom uvjetu:

Var brojevi = [ 1, -12, 8, -4, 25, 42 ]; uvjet funkcije(vrijednost, indeks, niz) ( prom. rezultat = laž; ako (vrijednost > 0) ( rezultat = istina; ) vrati rezultat; ); var pass = brojevi.svaki(uvjet); document.write(prošlo); // lažno

Metodi every() prosljeđuje se funkcija koja predstavlja uvjet kao parametar. Ova funkcija uzima tri parametra:

Uvjet funkcije (vrijednost, indeks, niz) ( )

Parametar vrijednosti predstavlja trenutni element niza koji se ponavlja, parametar indeksa predstavlja indeks tog elementa, a parametar niza prenosi referencu na niz.

U ovoj funkciji možemo provjeriti usklađenost prenesene vrijednosti elementa s nekim uvjetom. Na primjer, u ovom primjeru provjeravamo svaki element niza da vidimo je li veći od nule. Ako je veći, vraćamo vrijednost true, odnosno element ispunjava uvjet. Ako je manje, vrati false - element ne ispunjava uvjet.

Kao rezultat toga, kada se pozove metoda numbers.every(condition), ona prolazi kroz sve elemente niza brojeva i prosljeđuje ih jedan po jedan funkciji uvjeta. Ako ova funkcija vrati true za sve elemente, tada metoda every() vraća true. Ako barem jedan element ne odgovara uvjetu, tada metoda every() vraća false.

neki()

Metoda some() slična je metodi every(), samo što provjerava odgovara li barem jedan element uvjetu. I u ovom slučaju, some() metoda vraća true. Ako u nizu nema elemenata koji odgovaraju uvjetu, vraća se false:

Var brojevi = [ 1, -12, 8, -4, 25, 42 ]; uvjet funkcije(vrijednost, indeks, niz) ( var rezultat = laž; if (vrijednost === 8) ( rezultat = istina; ) vrati rezultat; ); var pass = brojevi.neki(uvjet); // istina

filtar()

Metoda filter(), poput some() i every(), prihvaća funkciju uvjeta. Ali u isto vrijeme vraća niz onih elemenata koji ispunjavaju ovaj uvjet:

Var brojevi = [ 1, -12, 8, -4, 25, 42 ]; uvjet funkcije(vrijednost, indeks, niz) ( prom. rezultat = laž; ako (vrijednost > 0) ( rezultat = istina; ) vrati rezultat; ); var filteredNumbers = brojevi.filter(uvjet); za (var i=0; i< filteredNumbers.length; i++) document.write(filteredNumbers[i] + "
");

Ispis preglednika:

1 8 25 42

forEach() i map()

Metode forEach() i map() ponavljaju elemente i izvode određene operacije na njima. Na primjer, da biste izračunali kvadrate brojeva u nizu, možete koristiti sljedeći kôd:

Var brojevi = [1, 2, 3, 4, 5, 6]; for(var i = 0; i "); }

Ali pomoću metode forEach() možete pojednostaviti ovu konstrukciju:

Var brojevi = [1, 2, 3, 4, 5, 6]; funkcija kvadrat(vrijednost, indeks, polje) ( var rezultat = vrijednost * vrijednost; dokument.write("Kvadrat broja " + vrijednost + " je " + rezultat + "
"); ); brojevi.zaSvaki(kvadrat);

Metoda forEach() uzima kao parametar istu funkciju u koju se, prilikom iteracije preko elemenata, prosljeđuje trenutni element koji se iterira i nad njim se izvode operacije.

Metoda map() slična je metodi forEach; ona također uzima kao parametar funkciju koja izvodi operacije na elementima niza, ali metoda map() vraća novi niz s rezultatima operacija na elementima niza.

Na primjer, upotrijebimo metodu karte za izračun kvadrata brojeva u nizu:

Var brojevi = [1, 2, 3, 4, 5, 6]; funkcija kvadrat(vrijednost, indeks, niz) ( vrati rezultat = vrijednost * vrijednost; ); var squareArray = numbers.map(square); document.write(squareArray);

Funkcija koja se prosljeđuje metodi map() prima trenutni element koji se ponavlja, izvodi operacije na njemu i vraća neku vrijednost. Ova vrijednost zatim ide u rezultirajući squareArray



reci prijateljima
Pročitajte također