Objektu īpašību atkārtošana. Visi veidi, kā atkārtot, izmantojot JavaScript masīvu Piezīme par izpildlaika objektiem

The katram() metode katram masīva elementam vienu reizi izpilda sniegto funkciju.

Šī interaktīvā piemēra avots tiek glabāts GitHub repozitorijā. Ja vēlaties piedalīties interaktīvo piemēru projektā, lūdzu, klonējiet https://github.com/mdn/interactive-examples un nosūtiet mums izvilkšanas pieprasījumu.

Sintakse

arr .forEach(callback(currentValue [, indekss [, masīvs]]) [, thisArg ]);

Parametri

atzvanīšana Funkcija, kas izpildāma katram elementam, izmantojot trīs argumentus: currentValue Pašreizējais elements, kas tiek apstrādāts masīvā. indekss Neobligāts Pašreizējā elementa indekss, kas tiek apstrādāts masīvā. masīvs Neobligāts Tika izsaukts masīvs forEach(). thisArg Izvēles vērtība, ko izmantot kā šo, izpildot atzvanīšanu.

Atdeves vērtība

Apraksts

forEach() vienu reizi izsauc nodrošināto atzvanīšanas funkciju katram masīva elementam augošā secībā. Tas netiek izsaukts indeksa rekvizītiem, kas ir dzēsti vai nav inicializēti (t.i., retos masīvos, ).

atzvanīšana tiek izsaukta ar trīs argumentiem:

  1. elementa vērtība
  2. elementa indekss
  3. masīva objekts, kas tiek šķērsots

Ja parametram forEach() tiek nodrošināts thisArg parametrs, tas tiks izmantots kā atzvanīšanas vērtība. Šī vērtība, kas galu galā ir novērojama, izmantojot atzvanīšanu, tiek noteikta saskaņā ar parastajiem noteikumiem, lai noteiktu funkciju .

ForEach() apstrādāto elementu diapazons ir iestatīts pirms pirmās atzvanīšanas izsaukšanas. Elementi, kas tiek pievienoti masīvam pēc forEach() izsaukuma sākuma, netiks apmeklēti, izmantojot atzvanīšanu. Ja esošie masīva elementi tiek mainīti vai dzēsti, to vērtība, kas nodota atzvanīšanai, būs vērtība brīdī, kad forEach() tos apmeklēs; elementi, kas tiek izdzēsti pirms apmeklējuma, netiek apmeklēti. Ja iterācijas laikā tiek noņemti jau apmeklētie elementi (piemēram, izmantojot Shift()), vēlākie elementi tiks izlaisti — skatiet piemēru tālāk .

forEach() izpilda atzvanīšanas funkciju vienu reizi katram masīva elementam; atšķirībā no map() vai reduce() tas vienmēr atgriež vērtību nenoteiktu un nav ķēdējams. Tipisks lietošanas gadījums ir blakusparādību izpilde ķēdes beigās.

forEach() nematē masīvu, kurā tas tiek izsaukts (lai gan atzvanīšana, ja tiek izsaukta, to var darīt).

ForEach() cilpu nevar apturēt vai pārtraukt, izņemot izņēmuma iespēju. Ja jums ir nepieciešama šāda rīcība, metode forEach() ir nepareizs rīks.

Priekšlaicīgu izbeigšanu var veikt ar:

Masīva metodes: every() , some() , find() un findIndex() pārbauda masīva elementus ar predikātu, kas atgriež patiesu vērtību, lai noteiktu, vai ir nepieciešama turpmāka iterācija.

Piemēri

Netiek veikta darbība ar inicializētām vērtībām (reti masīvi)

const arraySparse = ; ļaujiet numCallbackRuns = 0; arraySparse.forEach(function(element)( console.log(element); numCallbackRuns++; )); console.log("numCallbackRuns: ", numCallbackRuns); // 1 // 3 // 7 // numCallbackRuns: 3 // komentārs: kā redzat, trūkstošā vērtība no 3 līdz 7 neizsauca atzvanīšanas funkciju.

For cilpas pārvēršana par forEach

const items = ["item1", "item2", "item3"]; const copy = ; // pirms for (lai i=0; i Masīva satura drukāšana

Piezīme: Lai konsolē parādītu masīva saturu, varat izmantot console.table(), kas izdrukās formatētu masīva versiju. Šis piemērs ilustrē citu veidu, kā to izdarīt, izmantojot forEach() .

Šis kods reģistrē rindu katram masīva elementam:

Funkcija logArrayElements(elements, index, masīvs) ( console.log("a[" + index + "] = " + elements); ) // Ņemiet vērā, ka indekss 2 tiek izlaists, jo // šajā pozīcijā nav neviena vienuma masīvs. .forEach(logArrayElements); // žurnāli: // a = 2 // a = 5 // a = 9

Izmantojot šoArg

Šis (izdomāts) piemērs atjaunina objekta rekvizītus no katra ieraksta masīvā:

Funkcija Counter() ( this.sum = 0; this.count = 0; ) Counter.prototype.add = function(masīvs) ( array.forEach(function(entry) ( this.sum += ieraksts; ++this.count ; ), this); // ^---- Piezīme ); const obj = new Skaitītājs(); obj.add(); obj.count; // 3 obj.sum; // 16

Tā kā thisArg parametrs (this) tiek nodrošināts forEach() , tas tiek nodots atzvanīšanai katru reizi, kad tas tiek izsaukts, lai izmantotu kā šo vērtību.

Objekta kopēšanas funkcija

Šis kods izveido dotā objekta kopiju. Ir dažādi veidi, kā izveidot objekta kopiju; Šis ir tikai viens veids, un tas ir sniegts, lai izskaidrotu, kā Array.prototype.forEach() darbojas, izmantojot ECMAScript 5 Object.* meta rekvizītu funkcijas.

Funkcijas kopija(obj) ( const copy = Object.create(Object.getPrototypeOf(obj)); const propNames = Object.getOwnPropertyNames(obj); propNames.forEach(function(name) ( const desc = Object.getOwnPropertyDescriptor(obj, nosaukums) );Object.defineProperty(kopija, nosaukums, desc); )); atgriezt kopiju; ) const obj1 = ( a: 1, b: 2 ); const obj2 = kopija(obj1); // obj2 tagad izskatās kā obj1

Ja iterācijas laikā masīvs tiek mainīts, citi elementi var tikt izlaisti.

Nākamajā piemērā tiek reģistrēti "viens", "divi", "četri". Kad ieraksts satur vērtību "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 vārdi = ["viens", "divi", "trīs", "četri"]; vārdi.forEach(funkcija(vārds) ( konsole.log(vārds); if (vārds === "divi") (words.shift(); ) )); // viens // divi // četri

Izlīdziniet masīvu

Šis piemērs ir paredzēts tikai mācību nolūkos. Ja vēlaties saplacināt masīvu, izmantojot iebūvētās metodes, varat izmantot Array.prototype.flat() (paredzams, ka tā būs daļa no ES2019 un jau ir ieviesta dažās pārlūkprogrammās).

/** * Saplacina nodoto masīvu vienas dimensijas masīvā * * @params (masīvs) arr * @returns (masīvs) */ funkcija flatten(arr) ( const rezultāts = arr.forEach((i) => ( if (Array. isArray(i)) ( result.push(...flatten(i)) ) else (rezultāts.push(i) )) return result ) // Usage const problem = , 8, 9]] flatten(problem) //

Specifikācijas

Specifikācija Statuss komentēt
ECMAScript jaunākais melnraksts (ECMA-262)
Melnraksts
ECMAScript 2015 (6. izdevums, ECMA-262)
"Array.prototype.forEach" definīcija šajā specifikācijā.
Standarta
ECMAScript 5.1 (ECMA-262)
"Array.prototype.forEach" definīcija šajā specifikācijā.
Standarta Sākotnējā definīcija. Ieviests JavaScript 1.6.

Pārlūkprogrammu saderība

Saderības tabula šajā lapā ir ģenerēta no strukturētiem datiem. Ja vēlaties sniegt ieguldījumu datu apkopošanā, lūdzu, skatiet vietni https://github.com/mdn/browser-compat-data un nosūtiet mums izvilkšanas pieprasījumu.

Atjauniniet saderības datus vietnē GitHub

DarbvirsmaMobilaisServeris
ChromeMalaFirefoxInternet ExplorerOperaSafariAndroid tīmekļa skatsChrome Android ierīcēmFirefox operētājsistēmai AndroidOpera operētājsistēmai AndroidSafari operētājsistēmā iOSSamsung internetsNode.js
katramChrome Pilns atbalsts JāEdge Pilns atbalsts 12Firefox Pilns atbalsts 1.5IE Pilns atbalsts 9Opera Pilns atbalsts JāSafari Pilns atbalsts JāWebView Android Pilns atbalsts JāChrome Android Pilns atbalsts JāFirefox Android Pilns atbalsts 4Opera Android Pilns atbalsts JāSafari iOS Pilns atbalsts JāSamsung Internet Android Pilns atbalsts Jānodejs Pilns atbalsts Jā

2016. gada 12. marts

Mūsdienu JavaScript ir tā sauktās “iterācijas metodes”, kas tiek izmantotas, lai atkārtotu masīvus. Šajā apmācībā mēs apskatīsim šādas metodes:

katram

Metode .forEach() tiek izmantota brutālu spēku masīvs. Tā izsauc tā saukto atzvanīšanas funkciju, ar kuras palīdzību tiek nodoti trīs parametru vienums i, arr, kur:

  • item — masīva elements;
  • i ir masīva sērijas numurs;
  • arr ir pats masīvs, kas ir jāatkārto.

Lai būtu vieglāk saprast, kā izmantot šo metodi, apsveriet piemēru:

Var user=["admin","pass",31]; user.forEach(function(prece,i,user)( alert("Preces Nr. " + i + " : " + vienums); ));

Šo metodi var izmantot parastās cilpas vietā.

filtru

Filtrēšanai tiek izmantota metode .filter(), tā izmanto arī atzvanīšanas funkciju, bet izveido jaunu masīvu, ja masīva elementi atbilst vērtībai true:

Var arr=; var newArr=arr.filter(function(number)( atgriež skaitli< 0; }); alert(newArr); // выведет -34,-4

Šajā piemērā skaitļiem tiek pārbaudītas negatīvas vērtības, un izvade ir jauns masīvs ar šīm vērtībām. Jūs varat izdomāt savus nosacījumus; tiem nav obligāti jābūt skaitļiem.

katrs/daži

Šīs divas metodes ir līdzīgas viena otrai, un abas tiek izmantotas, lai pārbaudītu masīvu, tikai metodi .katrs() atgriež patieso vērtību, ja visas masīva vērtības atbilst norādītajam nosacījumam un metodei .some() atgriež true, ja vismaz viena vērtība atbilst nosacījumam:

Var arr=; alert(arr.every(function(number)( atgriešanās numurs< 0; })); // выведет false

Es ceru, ka ir skaidrs, ka, ja iepriekš minētajā piemērā mēs izmantojām kāda metode tad mēs būtu parādījuši vērtību true, nevis false.

karte

.map() metode pārveido masīvu un iegūst no tā jaunu. Viss tiek darīts, izsaucot atzvanīšanas funkciju:

Var arr=; var newArr=arr.map(funkcija(skaitlis)(atgriešanās numurs*2; )); brīdinājums(newArr);

Šajā piemērā mēs saņēmām jaunu masīvu ar dubultām elementu vērtībām.

samazināt/samazinātPa labi

Pēdējās metodes, kuras mēs apskatīsim, ir samazināšana un reducēšanaRight. Tos izmanto, lai apstrādātu katru masīva elementu, vienlaikus saglabājot starprezultātu. Metode atkārtojas caur katru elementu no kreisās puses uz labo, redukcijaRight rīkojas pretēji. Atšķirībā no citām metodēm, papildus atzvanīšanas funkcijai, šeit ir norādīts arī inicializācijas vērtības arguments - “sākotnējā vērtība”. Turklāt atzvanīšanas funkcija norāda “starprezultātu” - iepriekšējāVērtība Un pašreizējais vienums— pašreizējais masīva elements.

Apskatīsim piemēru:

Funkcija getSums(arr) ( var rezultāts = ; if (!arr.length) atgriež rezultātu; var totalSum = arr.reduceRight(function(sum, item) ( result.push(sum); return summa + vienums; )); rezultāts .push(totalSum); atgriezt rezultātu; ) alert(getSums()); // 1,3,6,10,15

Kas notika šajā piemērā? Mēs esam izveidojuši funkciju, kas ļauj iegūt jaunu masīvu ar elementiem, kas izveidoti no iepriekšējo summas. Turklāt elementu ziņojums nāk no beigām. Un šeit ir vienkāršāks piemērs, kurā es izveidoju funkciju, kas aprēķina masīva elementu summu:

Funkcija getSum(arr) ( var rezultāts = arr.reduce(function(sum, current) ( return summa + strāva )); atgriešanās rezultāts; ); brīdinājums(getSum()); Birkas: 

Sveiki! Pēdējā nodarbībā apskatījām, kas ir objekti un kāpēc tie ir vajadzīgi, un šodien apskatīsim, kā strādāt ar objekta īpašībām un kā reāli sakārtot visas šīs īpašības. Šiem nolūkiem tiek izmantota rekvizītu cilpa for..in (par cilpām varat lasīt JavaScript).

Cilpa uz...

Sintakse:

For (atslēgt obj) ( /* ... darbības ar objektu ... */ )

Cilpa for..in secīgi atkārtos objekta obj rekvizītus, atslēgā ierakstot katra rekvizīta nosaukumu.

Mainīgā deklarēšana for cilpā (var atslēga objektā obj)

Šajā cilpā varat deklarēt galveno mainīgo:

For (var taustiņš izvēlnē1) ( // ... )

Apskatīsim piemēru atkārtošanai, izmantojot objekta īpašības, izmantojot for...in cilpu:

Var menu = (platums: 400, augstums: 300, nosaukums: "Izvēlne Mana" ); for (var taustiņš izvēlnē) ( // šis kods darbosies katram objekta rekvizītam // ..un attiecīgi parādīs rekvizīta nosaukumu un tā vērtību alert("Key: " + key + " value: " + menu) ;)

Vēlos vērst jūsu uzmanību uz to, ka piemērā mēs izmantojām izvēlni kvadrātiekavās. Tas ir tāpēc, ka, ja rekvizīta nosaukumu saglabājam mainīgajā, tam varam piekļūt tikai ar kvadrātiekavām, bet ne ar punktu.

Cilpa… no

Ir arī jauna cilpa objektu un masīvu šķērsošanai. Tā sintakse ir ļoti līdzīga for...in cilpai, taču atšķirības ir tādas, ka tā neizvada masīva atslēgas vai indeksus, bet gan tā vērtības. Šeit ir piemērs:

Var menu = (platums: 400, augstums: 300, nosaukums: "Izvēlne Mana" ); for (izvēlnes var taustiņš) ( // šis kods darbosies katram objekta rekvizītam // ..un attiecīgi parādīs rekvizīta vērtību alert("value: " + key +","); //400, 300, "Izvēlne Mana")

Rekvizītu skaits objektā

Bet ko darīt, ja jums jāzina objekta rekvizītu skaits? Kā es to varu izdarīt?

Diemžēl šai problēmai nav gatavu risinājumu.

Vienkāršākais veids ir aplūkot rekvizītus un aprēķināt šādi:

Var menu = (platums: 400, augstums: 300, nosaukums: "Izvēlne Mana" ); var skaits = 0; for (var taustiņš izvēlnē) ( count++; ) alert("Kopējie rekvizīti: " + skaits);

Rezultāti

  • Lai atkārtotu objekta īpašības, tiek izmantota atslēgas cilpa: for (key in obj).

Uzdevumi

Nosakiet, vai objekts ir tukšs

Izveidojiet funkciju isEmptyObject(obj), kas atgriež true, ja objektam nav rekvizītu, un false, ja ir vismaz viens rekvizīts.

Tam vajadzētu darboties šādi:

Funkcija isEmptyObject(obj) ( /* jūsu kods */ ) var obj = (); brīdinājums(isEmptyObject(obj)); // true obj["8:30"] = "pieaugums"; brīdinājums(isEmptyObject(obj)); // viltus

Aprēķināt visu objekta īpašību vidējo aritmētisko

Ir algu objekts ar algām. Uzrakstiet kodu, kas parādīs visu algu vidējo aritmētisko.
Ja objekts ir tukšs, rezultātam jābūt 0.
Piemēram.

Tas darbojas šādi:

// NEPIECIEŠAMS ECMASCRIPT 2015+ var s, myStringArray = ["Sveiki", "Pasaule"]; for (s of myStringArray) ( // ... dariet kaut ko ar s ... )

Vai vēl labāk, jo ECMAScript 2015 nodrošina arī bloka tvēruma mainīgos ar let un const:

// NEPIECIEŠAMS ECMASCRIPT 2015+ const myStringArray = ["Sveiki", "Pasaule"]; for (const s of myStringArray) ( // ... darīt kaut ko ar s ... ) // s šeit vairs nav definēts

Piezīme par retiem masīviem: JavaScript masīvs var nesaglabāt tik daudz elementu, cik norādīts tā garumā ; šis paziņotais skaitlis ir vienkārši par vienu lielāks nekā augstākais indekss, kurā vērtība tiek saglabāta. Ja masīvā ir mazāk elementu, nekā norāda tā garums, tas tiek uzskatīts par retu. Piemēram, ir pilnīgi likumīgi izveidot masīvu ar elementiem tikai indeksos 3, 12 un 247; Šāda masīva garums ir norādīts kā 248, lai gan patiesībā tas saglabā tikai 3 vērtības. Ja mēģināt piekļūt elementam jebkurā citā indeksā, masīvam būs nedefinēta vērtība. Tātad, ja vēlaties "iterēt" masīvu, jums ir jāatbild uz jautājumu: vai vēlaties iterēt visā diapazonā, kas norādīts pēc tā garuma, un apstrādāt nedefinētu trūkstošo elementu, vai arī vēlaties apstrādāt tikai elementi, kas patiešām ir? Abām pieejām ir daudz pielietojumu; tas ir atkarīgs no tā, kādam nolūkam jūs izmantojat masīvu.

Ja atkārtojat masīvu ar for .. of , cilpas pamatteksts tiek izpildīts pēc garuma un cilpas vadības mainīgais tiek iestatīts uz nenoteiktu visiem elementiem, kas faktiski neatrodas masīvā. Atkarībā no jūsu “darīt kaut ko” koda detaļām šī darbība var būt tā, ko vēlaties, taču, ja tā nav tā, ko vēlaties, jums vajadzētu izmantot citu pieeju.

Protams, dažiem izstrādātājiem nav citas izvēles, kā vien izmantot citu pieeju, jo kāda iemesla dēļ viņi ir mērķēti uz JavaScript versiju, kas vēl netiek atbalstīta ... no .

Kamēr jūsu JavaScript ieviešana ir saderīga ar iepriekšējo ECMAScript specifikācijas versiju (kas, piemēram, izslēdz Internet Explorer versijas, kas vecākas par 9), cilpas vietā varat izmantot metodi Array#forEach iterator. Šajā gadījumā jūs nododat funkciju, kas tiks izsaukta katram masīva elementam:

Var myStringArray = [ "Sveiki", "Pasaule" ]; myStringArray.forEach(function(s) ( // ... darīt kaut ko ar s ... ));

Atšķirībā no ... of , .forEach izsauc funkciju tikai tiem elementiem, kas faktiski satur vērtības. Ja mēs izturēsim savu hipotētisko masīvu ar trim elementiem un garumu 248, tas izsauks funkciju tikai trīs reizes, nevis 248 reizes. Tas arī nošķir trūkstošos elementus un elementus, kas faktiski ir iestatīti uz nenoteiktu ; pēdējam tas joprojām izsauks funkciju, kā argumentu nododot nenoteiktu vērtību. Ja šādi vēlaties apstrādāt retus masīvus, .forEach varētu būt pareizais veids, pat ja jūsu tulkotājs atbalsta ... no .

Pēdējā opcija, kas darbojas visās JavaScript versijās, ir skaidra skaitīšanas cilpa. Jūs vienkārši saskaitāt no 0 līdz vienam mazāk par garumu un izmantojiet skaitītāju kā indeksu. Galvenā cilpa izskatās šādi:

Viena no šīs pieejas priekšrocībām ir tā, ka varat izvēlēties, kā rīkoties ar retiem masīviem; Iepriekš minētais kods izpildīs cilpas pamattekstu visā garumā, un s ir iestatīts uz undefined visiem trūkstošajiem elementiem, piemēram, .. no . Ja tā vietā vēlaties apstrādāt tikai esošus reta masīva elementus, piemēram, .forEach , indeksam varat pievienot vienkāršu pārbaudi:

Var i, s, myStringArray = [ "Sveiki", "Pasaule" ], len = myStringArray.length; priekš (i=0; i

Garuma vērtības piešķiršana lokālajam mainīgajam (pretēji pilnas myStringArray.length izteiksmes iekļaušanai cilpas nosacījumā) var būtiski ietekmēt veiktspēju, jo tā katru reizi izlaiž rekvizītu uzmeklēšanu līdz beigām; Lietojot Rhino savā mašīnā, paātrinājums ir 43%.

Varat redzēt, ka garuma kešatmiņa tiek veikta cilpas inicializācijas klauzulā, piemēram:

Var i, len, myStringArray = [ "Sveiki", "Pasaule" ]; for (len = myStringArray.length, i=0; i

Citu pieminētais for ... sintaksē tiek izmantots, lai pārvietotos caur objekta īpašībām; tā kā JavaScript masīvs ir tikai objekts ar skaitliskiem rekvizītu nosaukumiem (un automātiski atjauninātu garuma rekvizītu), teorētiski varat ar to izveidot cilpu masīvam. Bet problēma ir tā, ka tas neaprobežojas tikai ar skaitliskām īpašību vērtībām (atcerieties, ka pat metodes patiesībā ir tikai rekvizīti, kuru vērtība ir slēgšana), kā arī netiek garantēts, ka tas tiks atkārtots skaitliskā secībā. Tāpēc sintaksē esošo for ... nevajadzētu izmantot masīvu cilpai.

  • I. Iterācija reālos masīvos
    1. katrai metodei un saistītajām metodēm
    2. cilpai
    3. Pareiza for...in cilpas izmantošana
    4. for... of loop (netieša iteratora izmantošana)
    5. Skaidra iteratora izmantošana
  • II. Iterācija pār masīvam līdzīgiem objektiem
    1. Metožu izmantošana reālu masīvu atkārtošanai
    2. Konvertēt uz reālu masīvu
    3. Piezīme par izpildlaika objektiem

I. Iterācija reālos masīvos

Pašlaik ir trīs veidi, kā atkārtot reāla masīva elementus:

  1. metode Array.prototype.forEach ;
  2. klasika cilpai
  3. “pareizi” konstruēta... in cilpa.

Turklāt drīzumā līdz ar jaunā ECMAScript 6 (ES 6) standarta parādīšanos ir gaidāmas vēl divas metodes:

  1. for...of cilpa (netieša iteratora izmantošana);
  2. nepārprotama iteratora izmantošana.

1. ForEach metode un ar to saistītās metodes

Ja jūsu projekts ir izstrādāts, lai atbalstītu ECMAScript 5 (ES5) standarta funkcijas, varat izmantot vienu no tā jauninājumiem - metodi forEach.

Lietošanas piemērs:

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

Parasti, lai izmantotu forEach, ir jāpievieno es5-shim emulācijas bibliotēka pārlūkprogrammām, kuras sākotnēji neatbalsta šo metodi. Tajos ietilpst IE 8 un vecākas versijas, kas dažviet joprojām tiek izmantotas.

ForEach priekšrocība ir tāda, ka nav nepieciešams deklarēt vietējos mainīgos, lai saglabātu pašreizējā masīva elementa indeksu un vērtību, jo tie automātiski tiek nodoti atzvanīšanas funkcijai kā argumenti.

Ja uztraucaties par iespējamām izmaksām, kas saistītas ar katra elementa atzvanīšanu, neuztraucieties un izlasiet šo.

forEach ir paredzēts, lai iterētu visus masīva elementus, taču papildus tam ES5 piedāvā vairākas noderīgas metodes visu vai dažu elementu iterācijai, kā arī dažu darbību veikšanai ar tiem:

  • every - atgriež true , ja katram masīva elementam atzvanīšana atgriež vērtību , ko var pārvērst par patiesu .
  • daži — atgriež patiesu, ja vismaz vienam masīva elementam atzvanīšana atgriež vērtību, ko var pārvērst par patiesu.
  • filtrs — izveido jaunu masīvu, kas ietver tos sākotnējā masīva elementus, kuriem atzvanīšana atgriež true .
  • karte - izveido jaunu masīvu, kas sastāv no vērtībām, kuras atgrieztas atzvanīšanas laikā.
  • reducē - samazina masīvu līdz vienai vērtībai, katram masīva elementam pēc kārtas piemērojot atzvanīšanu, sākot ar pirmo (var noderēt masīva elementu un citu kopsavilkuma funkciju summas aprēķināšanai).
  • ReductionRight — darbojas līdzīgi, lai samazinātu, bet atkārtojas caur elementiem apgrieztā secībā.

2. Cilpai

Noteikumiem vecs:

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

Ja masīva garums ir nemainīgs visā cilpas garumā un pati cilpa pieder veiktspējai kritiskai koda sadaļai (kas ir maz ticams), varat izmantot “optimālāku” versiju, kas saglabā masīva garumu. :

Var a = ["a", "b", "c"]; var indekss, len; for (indekss = 0, len = a.garums; indekss< len; ++index) { console.log(a); }

Teorētiski šim kodam vajadzētu darboties nedaudz ātrāk nekā iepriekšējam.

Ja elementu secība nav svarīga, varat iet vēl tālāk optimizācijas ziņā un atbrīvoties no mainīgā masīva garuma glabāšanai, mainot meklēšanas secību uz pretējo:

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

Tomēr mūsdienu JavaScript dzinējos šādas optimizācijas spēles parasti neko nenozīmē.

3. Pareiza for...in cilpas lietošana

Ja jums ir ieteicams izmantot for...in cilpu, atcerieties, ka atkārtošana masīvos nav paredzēta. Pretēji izplatītajam nepareizajam priekšstatam, cilpa for...in atkārto nevis masīva indeksus, bet gan neskaitāmas objekta īpašības.

Tomēr dažos gadījumos, piemēram, atkārtošana retos masīvos, for...in var būt noderīga, ja vien veicat piesardzības pasākumus, kā parādīts tālāk esošajā piemērā:

// a - rets masīvs var a = ; a = "a"; a = "b"; a = "c"; for (var atslēga in a) ( if (a.hasOwnProperty(key) && /^0$|^d*$/.test(key) && atslēga<= 4294967294) { console.log(a); } }

Šajā piemērā katrā cilpas iterācijā tiek veiktas divas pārbaudes:

  1. ka masīvam ir savs īpašums, ko sauc par atslēgu (nav mantots no tā prototipa).
  2. šī atslēga ir virkne, kas satur vesela skaitļa decimālo attēlojumu, kura vērtība ir mazāka par 4294967294. No kurienes nāk pēdējais cipars? No ES5 masīva indeksa definīcijas, kas parāda, ka augstākais indekss, kas var būt masīva elementam, ir: (2^32 - 2) = 4294967294 .

Protams, šādas pārbaudes cilpas izpildes laikā aizņems nevajadzīgu laiku. Bet reta masīva gadījumā šī metode ir efektīvāka nekā for cilpa, jo šajā gadījumā tiek iterēti tikai tie elementi, kas ir skaidri definēti masīvā. Tātad iepriekš minētajā piemērā tiks veiktas tikai 3 iterācijas (indeksiem 0, 10 un 10000) salīdzinājumā ar 10001 for cilpā.

Lai nerakstītu tik apgrūtinošu pārbaudes kodu ikreiz, kad nepieciešams atkārtot masīvu, varat to ierakstīt kā atsevišķu funkciju:

Funkcija arrayHasOwnIndex(masīvs, atslēga) ( atgriež array.hasOwnProperty(key) && /^0$|^d*$/.test(key) && atslēga<= 4294967294; }

Tad cilpas korpuss no piemēra tiks ievērojami samazināts:

For (key in a) ( if (arrayHasOwnIndex(a, key)) ( console.log(a); ) )

Iepriekš apspriestais pārbaudes kods ir universāls, piemērots visiem gadījumiem. Bet tā vietā varat izmantot īsāku versiju, lai gan formāli tā nav pilnīgi pareiza, taču piemērota vairumam gadījumu:

For (key in a) ( if (a.hasOwnProperty(key) && String(parseInt(key, 10)) === key) ( console.log(a); ) )

4. For...of cilpa (netieša iteratora izmantošana)

ES6, kas joprojām ir melnraksta statusā, vajadzētu ieviest iteratorus JavaScript.

Iterators ir objekta ieviests protokols, kas definē standarta veidu, kā iegūt vērtību secību (galīgu vai bezgalīgu).
Objektam ir iterators, ja tas definē next() metodi, bezargumentu funkciju, kas atgriež objektu ar divām īpašībām:

  1. darīts (būla) — patiess, ja iterators ir sasniedzis iterējamās secības beigas. Pretējā gadījumā vērtība ir nepatiesa.
  2. vērtība — nosaka iteratora atgriezto vērtību. Var būt nedefinēts (trūkst), ja paveiktais rekvizīts ir patiess .

Daudzi iebūvētie objekti, t.sk. reāliem masīviem pēc noklusējuma ir iteratori. Vienkāršākais veids, kā izmantot iteratoru reālos masīvos, ir izmantot jauno for... of construct.

Piemērs izmantošanai...no:

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

Iepriekš minētajā piemērā cilpa for...of netieši izsauc masīva objekta iteratoru, lai iegūtu katru masīva vērtību.

5. Skaidra iteratora izmantošana

Iteratorus var izmantot arī skaidri, taču šajā gadījumā kods kļūst daudz sarežģītāks salīdzinājumā ar for...of cilpu. Tas izskatās apmēram šādi:

Var a = ["a", "b", "c"]; var ieraksts; while (!(ieraksts = a.next()).pabeigts) ( console.log(entry.value); )

II. Iterācija pār masīvam līdzīgiem objektiem

Papildus reāliem masīviem JavaScript ir arī masīviem līdzīgi objekti . Viņiem ir kopīgs ar reāliem masīviem, ka tiem ir garuma īpašība un īpašības, kas nosauktas kā skaitļi, kas atbilst masīva elementiem. Piemēri ietver NodeList kolekcijas DOM un argumentus pseido masīvu, kas ir pieejami jebkurā funkcijā/metodē.

1. Metožu izmantošana reālu masīvu atkārtošanai

Vismaz lielāko daļu, ja ne visas, iterācijas metožu reālos masīvos var izmantot, lai iterētu masīvam līdzīgus objektus.

Konstrukcijas for un for...in var pielietot masīviem līdzīgiem objektiem tieši tāpat kā reāliem masīviem.

forEach un citas Array.prototype metodes attiecas arī uz masīvam līdzīgiem objektiem. Lai to izdarītu, jāizmanto Function.call vai Function.apply .

Piemēram, ja vēlaties lietot forEach objekta Node rekvizītam childNodes, tas jādara šādi:

Array.prototype.forEach.call(node.childNodes, function(child) ( // kaut ko darīt ar bērnu objektu));

Lai šo triku būtu vieglāk izmantot atkārtoti, jūs varat deklarēt atsauci uz metodi Array.prototype.forEach atsevišķā mainīgajā un izmantot to kā saīsni:

// (Pieņemot, ka viss tālāk norādītais kods ir vienā tvērumā) var forEach = Array.prototype.forEach; // ... forEach.call(node.childNodes, function(child) ( // kaut ko darīt ar bērnu objektu));

Ja masīvam līdzīgam objektam ir iterators, to var tieši vai netieši izmantot, lai iterētu pa objektu tāpat kā reāliem masīviem.

2. Konvertējiet uz reālu masīvu

Ir arī vēl viens ļoti vienkāršs veids, kā atkārtot masīvam līdzīgu objektu: pārveidot to par reālu masīvu un izmantot jebkuru no iepriekš aprakstītajām metodēm, lai veiktu atkārtojumus reālos masīvos. Pārveidošanai varat izmantot vispārīgo metodi Array.prototype.slice, ko var lietot jebkuram masīvam līdzīgam objektam. Tas tiek darīts ļoti vienkārši, kā parādīts zemāk esošajā piemērā:

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

Piemēram, ja vēlaties pārveidot NodeList kolekciju faktiskā masīvā, jums ir nepieciešams kods, kas līdzīgs šim:

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

3. Piezīme par izpildlaika objektiem

Ja izmantojat Array.prototype metodes izpildlaika objektiem (piemēram, DOM kolekcijām), jums jāņem vērā, ka netiek garantēta šo metožu pareiza darbība visās izpildlaika vidēs (tostarp pārlūkprogrammās). Tas ir atkarīgs no konkrēta objekta uzvedības konkrētā izpildes vidē vai, precīzāk, no tā, kā šajā objektā tiek realizēta abstraktā darbība HasProperty. Problēma ir tā, ka ES5 standarts pats par sevi pieļauj objekta nepareizas darbības iespēju saistībā ar šo darbību (sk. §8.6.2).

Tāpēc ir svarīgi pārbaudīt Array.prototype metožu darbību katrā izpildlaika vidē (pārlūkā), kurā plānojat izmantot savu lietojumprogrammu.