Ponavljanje lastnosti v objektih. Vsi načini iteracije skozi matriko v JavaScriptu Opomba o predmetih izvajalnega okolja

The za vsakogar() metoda izvede podano funkcijo enkrat za vsak element polja.

Vir za ta interaktivni primer je shranjen v repozitoriju GitHub. Če bi radi prispevali k projektu interaktivnih primerov, prosimo, klonirajte https://github.com/mdn/interactive-examples in nam pošljite zahtevo za vleko.

Sintaksa

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

Parametri

povratni klic Funkcija za izvedbo na vsakem elementu, ki vzame tri argumente: currentValue Trenutni element, ki se obdeluje v matriki. index Izbirno Indeks trenutnega elementa, ki se obdeluje v matriki. array Izbirno Klicana je bila matrika forEach(). thisArg Izbirna vrednost za uporabo kot this pri izvajanju povratnega klica.

Povratna vrednost

Opis

forEach() pokliče posredovano funkcijo povratnega klica enkrat za vsak element v matriki v naraščajočem vrstnem redu. Ne kliče se za lastnosti indeksa, ki so bile izbrisane ali niso inicializirane (tj. na redkih nizih, ).

povratni klic se prikliče s tremi argumenti:

  1. vrednost elementa
  2. indeks elementa
  3. objekt Array, ki ga prečkate

Če je parameter thisArg na voljo forEach(), bo uporabljen kot vrednost za povratni klic this. Vrednost this, ki jo je na koncu mogoče opazovati s povratnim klicem, se določi v skladu z običajnimi pravili za določanje this, ki jih vidi funkcija.

Obseg elementov, ki jih obdela forEach(), je nastavljen pred prvim klicem povratnega klica. Elementi, ki so dodani matriki po začetku klica funkcije forEach(), ne bodo obiskani s povratnim klicem. Če se obstoječi elementi matrike spremenijo ali izbrišejo, bo njihova vrednost, posredovana povratnemu klicu, vrednost v času, ko jih forEach() obišče; elementi, ki so izbrisani pred obiskom, niso obiskani. Če so že obiskani elementi odstranjeni (npr. z uporabo shift()) med ponovitvijo, bodo kasnejši elementi preskočeni – glejte spodnji primer.

forEach() izvede funkcijo povratnega klica enkrat za vsak element polja; za razliko od map() ali reduce() vedno vrne vrednost nedefinirano in ni verižna. Tipičen primer uporabe je izvajanje stranskih učinkov na koncu verige.

forEach() ne spremeni matrike, na kateri je poklican (čeprav lahko povratni klic, če je priklican, to stori).

Zanko forEach() ne morete ustaviti ali prekiniti drugače kot z vrženjem izjeme. Če potrebujete takšno vedenje, je metoda forEach() napačno orodje.

Predčasna prekinitev se lahko izvede z:

Metode matrike: every() , some() , find() in findIndex() preizkusijo elemente matrike s predikatom, ki vrne resnično vrednost, da ugotovijo, ali je potrebna nadaljnja iteracija.

Primeri

Ni operacije za neinicializirane vrednosti (redke matrike)

const arraySparse = ; pusti numCallbackRuns = 0; arraySparse.forEach(funkcija(element)( console.log(element); numCallbackRuns++; )); console.log("numCallbackRuns: ", numCallbackRuns); // 1 // 3 // 7 // numCallbackRuns: 3 // komentar: kot lahko vidite, manjkajoča vrednost med 3 in 7 ni priklicala funkcije povratnega klica.

Pretvarjanje zanke for v forEach

const items = ["item1", "item2", "item3"]; const kopija =; // pred for (naj i=0; i Tiskanje vsebine matrike

Opomba:Če želite prikazati vsebino matrike v konzoli, lahko uporabite console.table(), ki bo natisnila oblikovano različico matrike. Naslednji primer ponazarja drug način, kako to storiti, z uporabo forEach().

Naslednja koda beleži vrstico za vsak element v matriki:

Function logArrayElements(element, index, array) ( console.log("a[" + index + "] = " + element); ) // Opazite, da je indeks 2 preskočen, ker na // tem mestu v niz. .forEach(logArrayElements); // dnevniki: // a = 2 // a = 5 // a = 9

Z uporabo thisArg

Naslednji (izmišljeni) primer posodobi lastnosti objekta iz vsakega vnosa v matriki:

Funkcija Counter() ( this.sum = 0; this.count = 0; ) Counter.prototype.add = function(array) ( array.forEach(function(entry) ( this.sum += entry; ++this.count ; ), to); // ^---- Opomba); const obj = nov števec(); obj.add(); obj.count; // 3 obj.vsota; // 16

Ker je parameter thisArg (this) na voljo za forEach() , je posredovan povratnemu klicu vsakič, ko je priklican, za uporabo kot vrednost this.

Funkcija kopiranja predmeta

Naslednja koda ustvari kopijo danega predmeta. Obstajajo različni načini za ustvarjanje kopije predmeta; naslednje je le en način in je predstavljeno za razlago delovanja Array.prototype.forEach() z uporabo funkcij meta lastnosti ECMAScript 5 Object.*.

Function 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)); const obj2 = kopija(obj1); // obj2 zdaj izgleda kot obj1

Če je matrika spremenjena med iteracijo, bodo drugi elementi morda preskočeni.

Naslednji primer beleži "ena", "dva", "štiri". Ko vnos, ki vsebuje vrednost "two" is reached, the first entry of the whole array is shifted off, which results 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() does not make a copy of the array before iterating.!}

Var besede = ["ena", "dva", "tri", "štiri"]; words.forEach(function(word) ( console.log(word); if (word === "two") ( words.shift(); ) )); // ena // dva // štiri

Sploščite niz

Naslednji primer je tukaj samo za namen učenja. Če želite sploščiti matriko z vgrajenimi metodami, lahko uporabite Array.prototype.flat() (predvidoma bo del ES2019 in je že implementiran v nekaterih brskalnikih).

/** * Splošči posredovano matriko v enodimenzionalni matriki * * @params (matrika) arr * @returns (matrika) */ function flatten(arr) ( const rezultat = arr.forEach((i) => ( if (Matrika. isArray(i)) ( result.push(...flatten(i)) else ( result.push(i) )) return result ) // Uporaba const problem = , 8, 9]] flatten(problem) / /

Specifikacije

Specifikacija Stanje Komentiraj
Najnovejši osnutek ECMAScript (ECMA-262)
Osnutek
ECMAScript 2015 (6. izdaja, ECMA-262)
Definicija "Array.prototype.forEach" v tej specifikaciji.
Standardno
ECMAScript 5.1 (ECMA-262)
Definicija "Array.prototype.forEach" v tej specifikaciji.
Standardno Začetna definicija. Implementirano v JavaScriptu 1.6.

Združljivost brskalnika

Tabela združljivosti na tej strani je ustvarjena iz strukturiranih podatkov. Če želite prispevati k podatkom, obiščite https://github.com/mdn/browser-compat-data in nam pošljite zahtevo za vleko.

Posodobite podatke o združljivosti na GitHub

NamizjeMobilniStrežnik
ChromeEdgeFirefoxinternet ExplorerOperaSafariSpletni pogled AndroidChrome za AndroidFirefox za AndroidOpera za AndroidSafari v sistemu iOSSamsung InternetNode.js
za vsakogarPopolna podpora za Chrome DaEdge Popolna podpora 12Firefox Popolna podpora 1.5IE Popolna podpora 9Opera Popolna podpora DaSafari Popolna podpora DaWebView Android Polna podpora DaPopolna podpora za Chrome Android DaFirefox Android Popolna podpora 4Opera Android Polna podpora DaSafari iOS Popolna podpora DaSamsung Internet Android Polna podpora Danodejs Popolna podpora Da

12. marec 2016

V sodobnem JavaScriptu obstajajo tako imenovane »iteracijske metode«, ki se uporabljajo za iteracijo po nizih. V tej vadnici bomo obravnavali naslednje metode:

za vsakogar

Metoda .forEach() se uporablja za Iskanje niz. Pokliče tako imenovano funkcijo povratnega klica, s pomočjo katere se posredujejo trije parametri item, i, arr, kjer:

  • postavka — element niza;
  • i je zaporedna številka polja;
  • arr je sama matrika, ki jo je treba ponoviti.

Za lažje razumevanje uporabe te metode si oglejte primer:

Var user=["admin","pass",31]; user.forEach(function(item,i,user)( alert("Vrednost št. postavke " + i + " : " + postavka); ));

To metodo lahko uporabite namesto običajne zanke for.

filter

Metoda .filter() se uporablja za filtriranje, uporablja tudi funkcijo povratnega klica, vendar ustvari novo matriko, če se elementi v matriki ujemajo z vrednostjo true:

Var arr=; var newArr=arr.filter(funkcija(število)( vrni številko< 0; }); alert(newArr); // выведет -34,-4

V tem primeru so številke preverjene za negativne vrednosti, rezultat pa je nova matrika s temi vrednostmi. Pogoje si lahko izmislite sami; ni nujno, da so to številke.

vsak/nekaj

Ti dve metodi sta si podobni in obe se uporabljata za preverjanje matrike, samo metoda .vsak () vrne true, če se vse vrednosti v matriki ujemajo s podanim pogojem in metodo .some() vrne true, če se vsaj ena vrednost ujema s pogojem:

Var arr=; alert(arr.every(function(number)( return number< 0; })); // выведет false

Upam, da je jasno, da če v zgornjem primeru, ki smo ga uporabili neka metoda potem bi prikazali vrednost true namesto false.

zemljevid

Metoda .map() transformira matriko in iz nje pridobi novo. Vse se izvede s klicem funkcije povratnega klica:

Var arr=; var newArr=arr.map(function(number)( return number*2; )); opozorilo(novoArr);

V tem primeru smo prejeli novo matriko z dvojnimi vrednostmi elementov.

zmanjšaj/zmanjšajDesno

Zadnji metodi, ki si ju bomo ogledali, sta reduce in reduceRight. Uporabljajo se za obdelavo vsakega elementa matrike ob shranjevanju vmesnega rezultata. Metoda ponavlja skozi vsak element od leve proti desni, reduceRight pa nasprotno. Za razliko od drugih metod je poleg funkcije povratnega klica tukaj določen tudi argument initialValue - "začetna vrednost". Poleg tega funkcija povratnega klica določa "vmesni rezultat" - prejšnjaVrednost in trenutnipredmet— trenutni element matrike.

Poglejmo primer:

Funkcija getSums(arr) ( var rezultat = ; if (!arr.length) vrne rezultat; var totalSum = arr.reduceRight(function(sum, item) ( result.push(sum); return sum + item; )); rezultat .push(totalSum); vrni rezultat (getSums()); // 1,3,6,10,15

Kaj se je zgodilo v tem primeru? Ustvarili smo funkcijo, ki nam omogoča, da dobimo novo matriko z elementi, ustvarjenimi iz vsote prejšnjih. Poleg tega poročilo elementov prihaja s konca. Tukaj je enostavnejši primer, v katerem sem ustvaril funkcijo, ki izračuna vsoto elementov v matriki:

Funkcija getSum(arr) ( var result = arr.reduce(function(sum, current) ( return sum + current )); vrni rezultat; ); opozorilo(getSum()); Oznake: 

Zdravo! V zadnji lekciji smo pogledali, kaj so predmeti in zakaj so potrebni, danes pa bomo pogledali, kako delati z lastnostmi predmeta in kako dejansko razvrstiti vse te lastnosti. Za te namene se uporablja zanka lastnosti for..in (o zankah lahko preberete v JavaScriptu).

Zanka za..in

Sintaksa:

Za (vnesite obj) ( /* ... dejanja z obj ... */ )

Zanka for..in bo zaporedoma prešla skozi lastnosti objekta obj in zapisala ime vsake lastnosti v ključ.

Deklaracija spremenljivke v zanki for (ključ var v obj)

V tej zanki lahko deklarirate ključno spremenljivko:

Za (tipka var v meniju 1) ( // ... )

Oglejmo si primer ponavljanja skozi lastnosti predmeta z uporabo zanke for...in:

Var menu = (širina: 400, višina: 300, naslov: "Meni Moj"); for (tipka var v meniju) ( // ta koda bo delovala za vsako lastnost predmeta // ..in bo prikazala ime lastnosti in ustrezno vrednost alert("Key: " + key + " value: " + menu) ;)

Rad bi vas opozoril na dejstvo, da smo v primeru uporabili meni v oglatih oklepajih. To je zato, ker če ime lastnosti shranimo v spremenljivko, potem lahko do nje dostopamo le prek oglatih oklepajev, ne pa tudi prek pike.

Zanka za...od

Obstaja tudi nova zanka za prečkanje predmetov in nizov. Njegova sintaksa je zelo podobna zanki for...in, razlika pa je v tem, da ne izpiše ključev ali indeksov matrike, temveč njene vrednosti. Tukaj je primer:

Var menu = (širina: 400, višina: 300, naslov: "Meni Moj"); for (var tipka menija) ( // ta koda bo delovala za vsako lastnost predmeta // ..in ustrezno prikazala vrednost lastnosti alert("value: " + key +","); //400, 300, "Meni Moj")

Število lastnosti v objektu

Kaj pa, če morate vedeti število lastnosti v predmetu? Kako naj to storim?

Na žalost za to težavo ni pripravljenih rešitev.

Najlažji način je, da preletite lastnosti in izračunate na naslednji način:

Var menu = (širina: 400, višina: 300, naslov: "Meni Moj"); spremenljivo število = 0; for (tipka var v meniju) ( count++; ) alert("Skupaj lastnosti: " + count);

Rezultati

  • Za ponavljanje skozi lastnosti predmeta se uporablja ključna zanka: for (ključ v obj).

Naloge

Ugotovite, ali je predmet prazen

Ustvarite funkcijo isEmptyObject(obj), ki vrne true, če objekt nima lastnosti, in false, če obstaja vsaj ena lastnost.

Delovati bi moralo takole:

Funkcija isEmptyObject(obj) ( /* vaša koda */ ) var obj = (); opozorilo(isEmptyObject(obj)); // true obj["8:30"] = "vzpon"; opozorilo(isEmptyObject(obj)); // napačno

Izračunajte aritmetično sredino vseh lastnosti predmeta

Obstaja plačni objekt s plačami. Napišite kodo, ki bo izpisala aritmetično povprečje vseh plač.
Če je predmet prazen, mora biti rezultat 0.
Na primer.

Deluje takole:

// ZAHTEVA ECMASCRIPT 2015+ var s, myStringArray = ["Pozdravljeni", "Svet"]; for (s of myStringArray) ( // ... narediti nekaj z s ... )

Ali še bolje, saj ECMAScript 2015 ponuja tudi spremenljivke z obsegom bloka z let in const:

// ZAHTEVA ECMASCRIPT 2015+ const myStringArray = ["Pozdravljeni", "Svet"]; for (const s of myStringArray) ( // ... narediti nekaj s s ... ) // s ni več definiran tukaj

Opomba o redkih nizih: niz v JavaScriptu morda dejansko ne shrani toliko elementov, kot je določeno v njegovi dolžini; to prijavljeno število je preprosto za eno večje od najvišjega indeksa, pri katerem je vrednost shranjena. Če niz vsebuje manj elementov, kot kaže njegova dolžina, pravimo, da je redek. Na primer, popolnoma zakonito je imeti matriko z elementi samo pri indeksih 3, 12 in 247; Dolžina takšne matrike je določena kot 248, čeprav dejansko hrani le 3 vrednosti. Če poskusite dostopati do elementa na katerem koli drugem indeksu, bo imela matrika nedefinirano vrednost. Torej, ko želite "iterirati" matriko, imate vprašanje, na katerega je treba odgovoriti: ali želite iterirati čez celoten obseg, določen z njegovo dolžino, in obdelati nedefinirano za morebitne manjkajoče elemente ali želite obdelati le elementi dejansko prisotni? Obstaja veliko aplikacij za oba pristopa; odvisno je samo od tega, za kaj uporabljate niz.

Če ponovite matriko z for .. of , se telo zanke izvede po dolžini in spremenljivka za nadzor zanke je nastavljena na nedefinirano za vse elemente, ki dejansko niso v matriki. Odvisno od podrobnosti vaše kode »naredi nekaj« je to vedenje morda tisto, kar želite, če pa ni tisto, kar želite, uporabite drugačen pristop.

Seveda nekateri razvijalci vseeno nimajo druge izbire, kot da uporabijo drugačen pristop, ker iz neznanega razloga ciljajo na različico JavaScripta, ki še ni podprta za ... od .

Dokler je vaša implementacija JavaScripta združljiva s prejšnjo različico specifikacije ECMAScript (ki na primer izključuje različice Internet Explorerja pred 9), lahko uporabite metodo iteratorja Array#forEach namesto zanke. V tem primeru posredujete funkcijo, ki bo klicana za vsak element v matriki:

Var myStringArray = [ "Pozdravljeni", "Svet" ]; myStringArray.forEach(function(s) ( // ... narediti nekaj s s ... ));

Za razliko od for ... of, .forEach samo pokliče funkcijo za elemente, ki dejansko vsebujejo vrednosti. Če posredujemo našo hipotetično matriko s tremi elementi in dolžino 248, bo funkcija poklicala samo trikrat, ne pa 248-krat. Prav tako razlikuje med manjkajočimi elementi in elementi, ki so dejansko nastavljeni na nedefinirano; pri slednjem bo še vedno poklical funkcijo in posredoval nedefinirano vrednost kot argument. Če želite tako ravnati z redkimi nizi, je .forEach morda prava pot, tudi če vaš prevajalnik podpira za ... od .

Zadnja možnost, ki deluje v vseh različicah JavaScripta, je eksplicitna štetna zanka. Preprosto štejete od 0 do ena manj od dolžine in uporabite števec kot indeks. Glavna zanka izgleda takole:

Ena prednost tega pristopa je, da lahko izberete, kako ravnati z redkimi nizi; Zgornja koda bo zagnala telo zanke po celotni dolžini s s nastavljenim na nedefinirano za vse manjkajoče elemente, na primer za .. od . Če namesto tega želite obdelati samo dejansko obstoječe elemente redke matrike, kot je .forEach, lahko indeksu dodate preprosto preverjanje:

Var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length; za (i=0; i

Dodeljevanje vrednosti dolžine lokalni spremenljivki (v nasprotju z vključitvijo celotnega izraza myStringArray.length v pogoj zanke) ima lahko pomemben vpliv na zmogljivost, ker vsakič preskoči iskanje lastnosti vse do konca; Pri uporabi Rhino na mojem računalniku je pospešek 43 %.

Vidite lahko, da se predpomnjenje dolžine izvaja v klavzuli o inicializaciji zanke, takole:

Var i, len, myStringArray = [ "Pozdravljeni", "Svet" ]; za (len = myStringArray.length, i=0; i

For ... v sintaksi, ki so jo omenili drugi, se uporablja za pomikanje po lastnostih predmeta; ker je matrika v JavaScriptu le objekt s številskimi imeni lastnosti (in samodejno posodobljeno lastnostjo dolžine), bi lahko teoretično z njo zankali matriko. Toda težava je v tem, da ni omejena na številske vrednosti lastnosti (ne pozabite, da so tudi metode v resnici le lastnosti, katerih vrednost je zaprtje), niti ni zagotovljeno, da se bo ponovila v številčnem vrstnem redu. Zato se for ... v sintaksi ne bi smelo uporabljati za zankanje po nizih.

  • I. Ponavljanje po realnih nizih
    1. za vsako metodo in sorodne metode
    2. za zanko
    3. Pravilna uporaba zanke for...in
    4. zanka for...of (implicitna uporaba iteratorja)
    5. Eksplicitna uporaba iteratorja
  • II. Ponavljanje po predmetih, podobnih nizu
    1. Uporaba metod za ponavljanje resničnih nizov
    2. Pretvori v pravo matriko
    3. Opomba o izvajalnih objektih

I. Ponavljanje po realnih nizih

Trenutno obstajajo trije načini za ponavljanje elementov realnega niza:

  1. metoda Array.prototype.forEach ;
  2. klasična for zanka
  3. »pravilno« zgrajena zanka for...in.

Poleg tega se kmalu, s prihodom novega standarda ECMAScript 6 (ES 6), pričakujeta še dve metodi:

  1. zanka for...of (implicitna uporaba iteratorja);
  2. eksplicitna uporaba iteratorja.

1. Metoda forEach in sorodne metode

Če je vaš projekt zasnovan tako, da podpira funkcije standarda ECMAScript 5 (ES5), lahko uporabite eno od njegovih novosti - metodo forEach.

Primer uporabe:

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

Na splošno uporaba forEach zahteva povezavo emulacijske knjižnice es5-shim za brskalnike, ki izvorno ne podpirajo te metode. Sem sodijo IE 8 in starejši, ki so ponekod še v uporabi.

Prednost forEach je, da ni treba deklarirati lokalnih spremenljivk za shranjevanje indeksa in vrednosti trenutnega elementa matrike, saj se samodejno posredujejo funkciji povratnega klica kot argumenti.

Če vas skrbi morebitni strošek povratnega klica za vsak element, ne skrbite in preberite to.

forEach je zasnovan za ponavljanje skozi vse elemente matrike, vendar poleg tega ES5 ponuja več uporabnih metod za ponavljanje skozi vse ali nekatere elemente in izvajanje nekaterih dejanj na njih:

  • vsak vrne true, če za vsak element matrike povratni klic vrne vrednost, ki jo je mogoče pretvoriti v true.
  • some - vrne true, če za vsaj en element matrike povratni klic vrne vrednost, ki jo je mogoče pretvoriti v true.
  • filter - ustvari novo matriko, ki vključuje tiste elemente izvirne matrike, za katere povratni klic vrne true.
  • zemljevid - ustvari novo matriko, sestavljeno iz vrednosti, ki jih vrne povratni klic.
  • zmanjšati - zmanjša matriko na eno samo vrednost, pri čemer uporabi povratni klic za vsak element matrike po vrsti, začenši s prvim (lahko je uporabno za izračun vsote elementov matrike in druge funkcije povzetka).
  • reduceRight - deluje podobno kot reduce, vendar ponavlja elemente v obratnem vrstnem redu.

2. Za zanko

Dobro staro za pravila:

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

Če je dolžina niza konstantna v celotni zanki in sama zanka pripada delu kode, ki je kritičen za zmogljivost (kar je malo verjetno), potem lahko uporabite »bolj optimalno« različico for, ki shrani dolžino niza :

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

V teoriji bi morala ta koda delovati nekoliko hitreje kot prejšnja.

Če vrstni red elementov ni pomemben, lahko greste še dlje v smislu optimizacije in se znebite spremenljivke za shranjevanje dolžine polja, tako da vrstni red iskanja spremenite v obratno:

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

Vendar v sodobnih motorjih JavaScript takšne optimizacijske igre običajno ne pomenijo nič.

3. Pravilna uporaba zanke for...in

Če vam svetujemo uporabo zanke for...in, ne pozabite, da ponavljanje po nizih ni tisto, čemur je namenjeno. V nasprotju s pogostim napačnim prepričanjem zanka for...in ne iterira čez matrične indekse, temveč skozi našteve lastnosti predmeta.

Vendar pa je v nekaterih primerih, kot je ponavljanje po redkih nizih, for...in lahko koristen, če upoštevate previdnostne ukrepe, kot je prikazano v spodnjem primeru:

// a - redka matrika var a = ; a = "a"; a = "b"; a = "c"; for (var key in a) ( if (a.hasOwnProperty(key) && /^0$|^d*$/.test(key) && key<= 4294967294) { console.log(a); } }

V tem primeru se pri vsaki ponovitvi zanke izvedeta dve preverjanji:

  1. da ima niz svojo lastnost, imenovano ključ (ki ni podedovana od svojega prototipa).
  2. ta ključ je niz, ki vsebuje decimalno predstavitev celega števila, katerega vrednost je manjša od 4294967294. Od kod prihaja zadnja številka? Iz definicije matričnega indeksa v ES5, ki kaže, da je najvišji indeks, ki ga lahko ima element v matriki, naslednji: (2^32 - 2) = 4294967294 .

Seveda bodo takšna preverjanja vzela nepotreben čas pri izvajanju zanke. Toda v primeru redke matrike je ta metoda učinkovitejša od zanke for, saj se v tem primeru ponavljajo samo tisti elementi, ki so eksplicitno definirani v matriki. Torej bodo v zgornjem primeru izvedene samo 3 ponovitve (za indekse 0, 10 in 10000) - v primerjavi z 10001 v zanki for.

Da ne bi pisali tako okorne kontrolne kode vsakič, ko morate iterirati skozi matriko, jo lahko napišete kot ločeno funkcijo:

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

Potem bo telo zanke iz primera znatno zmanjšano:

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

Zgoraj obravnavana kontrolna koda je univerzalna, primerna za vse primere. Toda namesto tega lahko uporabite krajšo različico, čeprav formalno ni povsem pravilna, vendar je kljub temu primerna za večino primerov:

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

4. Zanka za...of (implicitna uporaba iteratorja)

ES6, ki je še vedno v osnutku, bi moral uvesti iteratorje v JavaScript.

Iterator je protokol, ki ga izvaja objekt, ki definira standardni način za pridobitev zaporedja vrednosti (končnega ali neskončnega).
Objekt ima iterator, če definira metodo next(), funkcijo brez argumentov, ki vrne objekt z dvema lastnostma:

  1. done (boolean) - res, če je iterator dosegel konec zaporedja, ki ga je mogoče ponoviti. V nasprotnem primeru je vrednost false.
  2. vrednost - definira vrednost, ki jo vrne iterator. Lahko je nedefinirano (manjka), če je lastnost done pravilna.

Veliko vgrajenih objektov, vklj. pravi nizi imajo privzeto iteratorje. Najenostavnejši način za uporabo iteratorja na realnih nizih je uporaba konstrukcije new for...of.

Primer uporabe za...of:

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

V zgornjem primeru zanka for...of implicitno pokliče iterator predmeta Array, da pridobi vsako vrednost matrike.

5. Eksplicitna uporaba iteratorja

Iteratorje je mogoče uporabiti tudi eksplicitno, vendar v tem primeru koda postane veliko bolj zapletena v primerjavi z zanko for...of. Videti je nekako takole:

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

II. Ponavljanje po predmetih, podobnih nizu

Poleg pravih nizov so v JavaScriptu tudi predmeti podobni nizu . Z realnimi nizi jim je skupno to, da imajo lastnost dolžine in lastnosti, imenovane kot številke, ki ustrezajo elementom niza. Primeri vključujejo DOM zbirke NodeList in psevdomatriko argumentov, ki je na voljo znotraj katere koli funkcije/metode.

1. Uporaba metod za ponavljanje realnih nizov

Vsaj večino, če ne vse, metode ponavljanja po realnih nizih je mogoče uporabiti za ponavljanje objektov, podobnih nizom.

Konstrukti for in for...in se lahko uporabijo za objekte, podobne matrikam, na povsem enak način kot za prave nize.

forEach in druge metode Array.prototype veljajo tudi za predmete, podobne matriki. Če želite to narediti, morate uporabiti Function.call ali Function.apply.

Na primer, če želite uporabiti forEach za lastnost childNodes objekta Node, bi to storili takole:

Array.prototype.forEach.call(node.childNodes, function(child) ( // naredi nekaj s podrejenim objektom));

Za lažjo ponovno uporabo tega trika lahko deklarirate sklic na metodo Array.prototype.forEach v ločeni spremenljivki in jo uporabite kot bližnjico:

// (Ob predpostavki, da je vsa spodnja koda v istem obsegu) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // naredi nekaj s podrejenim objektom));

Če ima matriki podoben objekt iterator, ga je mogoče uporabiti eksplicitno ali implicitno za ponavljanje po objektu na enak način kot za prave nize.

2. Pretvori v pravo matriko

Obstaja tudi drug, zelo preprost način za ponavljanje po predmetu, podobnem matriki: pretvorite ga v pravo matriko in uporabite katero koli od zgoraj opisanih metod za iteracijo po resničnih nizih. Za pretvorbo lahko uporabite generično metodo Array.prototype.slice, ki jo lahko uporabite za kateri koli predmet, podoben matriki. To se naredi zelo preprosto, kot je prikazano v spodnjem primeru:

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

Če bi na primer želeli pretvoriti zbirko NodeList v dejansko matriko, bi potrebovali kodo nekaj takega:

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

3. Opomba o izvajalnih objektih

Če metode Array.prototype uporabite za objekte izvajalnega okolja (kot so zbirke DOM), se morate zavedati, da ni zajamčeno, da bodo te metode pravilno delovale v vseh izvajalnih okoljih (vključno z brskalniki). To je odvisno od obnašanja določenega objekta v določenem izvajalnem okolju ali natančneje od tega, kako je v tem objektu implementirana abstraktna operacija HasProperty. Težava je v tem, da sam standard ES5 dopušča možnost, da se predmet ne obnaša pravilno glede na to operacijo (glejte §8.6.2).

Zato je pomembno, da preizkusite delovanje metod Array.prototype v vsakem izvajalnem okolju (brskalniku), v katerem nameravate uporabljati svojo aplikacijo.