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:
- elementa vērtība
- elementa indekss
- 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; iPiezī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
Darbvirsma | Mobilais | Serveris | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Chrome | Mala | Firefox | Internet Explorer | Opera | Safari | Android tīmekļa skats | Chrome Android ierīcēm | Firefox operētājsistēmai Android | Opera operētājsistēmai Android | Safari operētājsistēmā iOS | Samsung internets | Node.js | |
katram | Chrome Pilns atbalsts Jā | Edge Pilns atbalsts 12 | Firefox Pilns atbalsts 1.5 | IE Pilns atbalsts 9 | Opera Pilns atbalsts Jā | Safari Pilns atbalsts Jā | WebView Android Pilns atbalsts Jā | Chrome Android Pilns atbalsts Jā | Firefox Android Pilns atbalsts 4 | Opera 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. Pašlaik ir trīs veidi, kā atkārtot reāla masīva elementus: Turklāt drīzumā līdz ar jaunā ECMAScript 6 (ES 6) standarta parādīšanos ir gaidāmas vēl divas 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: 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ē. 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: 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); ) ) 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). 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. 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); ) 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ē. 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. 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); 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.I. Iterācija reālos masīvos
1. ForEach metode un ar to saistītās metodes
2. Cilpai
3. Pareiza for...in cilpas lietošana
4. For...of cilpa (netieša iteratora izmantošana)
Objektam ir iterators, ja tas definē next() metodi, bezargumentu funkciju, kas atgriež objektu ar divām īpašībām: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ējiet uz reālu masīvu
3. Piezīme par izpildlaika objektiem