Tādi lasītāji kā jūs palīdz atbalstīt MUO. Veicot pirkumu, izmantojot saites mūsu vietnē, mēs varam nopelnīt filiāles komisiju. Lasīt vairāk.

Datu kolekcijas atkārtošana, izmantojot tradicionālās cilpas, var ātri kļūt apgrūtinoša un lēna, it īpaši, ja tiek apstrādāts liels datu apjoms.

JavaScript ģeneratori un iteratori nodrošina risinājumu efektīvai iterācijai lielās datu kolekcijās. Izmantojot tos, varat kontrolēt iterācijas plūsmu, iegūt vērtības pa vienam, kā arī apturēt un atsākt iterācijas procesu.

Šeit jūs apskatīsit JavaScript iteratora pamatus un iekšējos elementus, kā arī to, kā jūs varat ģenerēt iteratoru manuāli un izmantojot ģeneratoru.

JavaScript iteratori

Iterators ir JavaScript objekts, kas ievieš iteratora protokolu. Šie objekti to dara, ja tiem ir a Nākamais metodi. Šī metode atgriež objektu, kas īsteno IteratorResult saskarne.

The IteratorResult interfeiss ietver divas īpašības: darīts un vērtību. The darīts īpašums ir Būla vērtība, kas atgriežas viltus ja iterators var radīt nākamo vērtību savā secībā vai taisnība ja iterators ir pabeidzis savu secību.

instagram viewer

The vērtību rekvizīts ir JavaScript vērtība, ko iterators atgriež tās secības laikā. Kad iterators pabeidz savu secību (kad darītstaisnība), šis īpašums atgriežas nenoteikts.

Kā norāda nosaukums, iteratori ļauj “iterēt” JavaScript objektus, piemēram, masīvus vai kartes. Šāda rīcība ir iespējama iterējamā protokola dēļ.

Programmā JavaScript iterējamais protokols ir standarta veids, kā definēt objektus, kurus varat atkārtot, piemēram, par...no cilpa.

Piemēram:

konst augļi = ["Banāns", "Mango", "Ābols", "Vīnogas"];

priekš (konst iterators no augļi) {
konsole.log (iterators);
}

/*
Banāns
Mango
Apple
Vīnogas
*/

Šis piemērs atkārtojas augļiem masīvs, izmantojot a par...no cilpa. Katrā iterācijā tas konsolē reģistrē pašreizējo vērtību. Tas ir iespējams, jo masīvi ir atkārtojami.

Daži JavaScript veidi, piemēram, masīvi, virknes, Komplekti un kartes, ir iebūvēti atkārtojumi, jo tie (vai kāds no objektiem, kas atrodas to prototipu ķēdē) īsteno an @@iterators metodi.

Citi veidi, piemēram, objekti, pēc noklusējuma nav atkārtojami.

Piemēram:

konst iterObject = {
automašīnas: ["Tesla", "BMW", "Toyota"],
dzīvnieki: ["Kaķis", "Suns", "Kammis"],
ēdiens: ["Burgeri", "Pica", "Makaroni"],
};

priekš (konst iterators no iterObject) {
konsole.log (iterators);
}

// Tipa kļūda: iterObject nav atkārtojams

Šis piemērs parāda, kas notiek, mēģinot atkārtot objektu, kas nav atkārtojams.

Objekta atkārtošana

Lai objektu padarītu iterējamu, ir jārealizē a Simbols.iterators metode uz objektu. Lai šī metode kļūtu atkārtojama, tai ir jāatgriež objekts, kas ievieš IteratorResult saskarne.

The Simbols.iterators simbols kalpo tam pašam mērķim kā @@iterators un to var lietot aizvietojami “specifikācijā”, bet ne kodā kā @@iterators nav derīga JavaScript sintakse.

Tālāk sniegtie kodu bloki sniedz piemēru, kā objektu padarīt iterējamu, izmantojot iterObject.

Pirmkārt, pievienojiet Simbols.iterators metode uz iterObject izmantojot funkcija deklarācija.

Tā kā:

iterObject[Simbols.iterator] = funkciju () {
// Turpmākie kodu bloki iet šeit...
}

Pēc tam jums būs jāpiekļūst visām atslēgām objektā, kuru vēlaties padarīt atkārtojamu. Jūs varat piekļūt taustiņiem, izmantojot Object.keys metode, kas atgriež objekta uzskaitāmo īpašību masīvu. Lai atgrieztu masīvu iterObject’s atslēgas, padodiet garām šis atslēgvārds kā arguments Object.keys.

Piemēram:

ļaut objProperties = Objekts.keys(šis)

Piekļuve šim masīvam ļaus definēt objekta iterācijas uzvedību.

Tālāk jums ir jāseko līdzi objekta iterācijām. To var panākt, izmantojot skaitītāja mainīgos.

Piemēram:

ļaut propertyIndex = 0;
ļaut bērnsIndekss = 0;

Jūs izmantosit pirmo skaitītāja mainīgo, lai izsekotu objekta īpašībām, un otro, lai izsekotu īpašuma bērniem.

Pēc tam jums būs jāievieš un jāatgriež Nākamais metodi.

Tā kā:

atgriezties {
Nākamais() {
// Turpmākie kodu bloki iet šeit...
}
}

Iekšpusē Nākamais metodi, jums būs jāapstrādā malas gadījums, kas rodas, kad viss objekts ir iterēts. Lai apstrādātu malas korpusu, jums ir jāatgriež objekts ar vērtību iestatīts uz nenoteikts un darīts iestatīts uz taisnība.

Ja šis gadījums netiek apstrādāts, mēģinājums atkārtot objektu radīs bezgalīgu cilpu.

Tālāk ir norādīts, kā rīkoties ar malas korpusu.

ja (īpašuma indekss > objProperties.garums- 1) {
atgriezties {
vērtība: nenoteikts,
darīts: taisnība,
};
}

Pēc tam jums būs jāpiekļūst objekta rekvizītiem un to pakārtotajiem elementiem, izmantojot iepriekš norādītos skaitītāju mainīgos.

Tā kā:

// Piekļuve vecāku un bērnu īpašumiem
konst īpašības = šis[objProperties[propertyIndex]];

konst īpašums = rekvizīti[bērnindekss];

Tālāk jums ir jāievieš zināma loģika skaitītāja mainīgo palielināšanai. Loģikai vajadzētu atiestatīt bērnsIndekss kad rekvizīta masīvā vairs nav elementu, un pāriet uz nākamo objekta rekvizītu. Turklāt tam vajadzētu palielināties bērnsIndekss, ja pašreizējā īpašuma masīvā joprojām ir elementi.

Piemēram:

// Indeksa palielināšanas loģika
if (childIndex >= property.length - 1) {
// ja bērnu masīvā vairs nav elementu
// atiestatītbērnsrādītājs
bērnsIndekss = 0;

// Pāriet uz nākamo īpašumu
propertyIndex++;
} cits {
// Pāriet uz nākamo elementu bērnu masīvā
bērnsIndekss++
}

Visbeidzot atgrieziet objektu ar darīts rekvizīts iestatīts uz viltus un vērtību rekvizīts ir iestatīts uz pašreizējo pakārtoto elementu iterācijā.

Piemēram:

atgriezties {
darīts: viltus,
vērtība: īpašums,
};

Jūsu pabeigts Simbols.iterators funkcijai jābūt līdzīgai tālāk norādītajam koda blokam:

iterObject[Simbols.iterator] = funkciju () {
konst objProperties = Objekts.keys(šis);
ļaut propertyIndex = 0;
ļaut bērnsIndekss = 0;

atgriezties {
Nākamais: () => {
//Apstrādā malas lietu
ja (īpašuma indekss > objProperties.garums- 1) {
atgriezties {
vērtība: nenoteikts,
darīts: taisnība,
};
}

// Piekļuve vecāku un bērnu īpašumiem
konst īpašības = šis[objProperties[propertyIndex]];

konst īpašums = rekvizīti[bērnindekss];

// Indeksa palielināšanas loģika
if (childIndex >= property.length - 1) {
// ja bērnu masīvā vairs nav elementu
// atiestatītbērnsrādītājs
bērnsIndekss = 0;

// Pāriet uz nākamo īpašumu
propertyIndex++;
} cits {
// Pāriet uz nākamo elementu bērnu masīvā
bērnsIndekss++
}

atgriezties {
darīts: viltus,
vērtība: īpašums,
};
},
};
};

Skriešana a par...no cilpa ieslēgta iterObject pēc šīs ieviešanas netiks parādīta kļūda, jo tā īsteno a Simbols.iterators metodi.

Iteratoru manuāla ieviešana, kā mēs to darījām iepriekš, nav ieteicama, jo tajā ir ļoti daudz kļūdu, un loģiku var būt grūti pārvaldīt.

JavaScript ģeneratori

JavaScript ģenerators ir funkcija, kuras izpildi var apturēt un atsākt jebkurā brīdī. Šī darbība ļauj tai laika gaitā izveidot vērtību secību.

Ģeneratora funkcija, kas atgriež ģeneratoru, nodrošina alternatīvu iteratoru izveidei.

Ģeneratora funkciju varat izveidot tāpat kā funkcijas deklarāciju JavaScript. Vienīgā atšķirība ir tā, ka jums ir jāpievieno zvaigznīte (*) funkcijas atslēgvārdam.

Piemēram:

funkciju* piemērs () {
atgriezties"Ģenerators"
}

Izsaucot parasto funkciju JavaScript, tā atgriež tās norādīto vērtību atgriezties atslēgvārds vai nenoteikts citādi. Bet ģeneratora funkcija nekavējoties neatgriež nekādu vērtību. Tas atgriež ģeneratora objektu, kuru varat piešķirt mainīgajam.

Lai piekļūtu iteratora pašreizējai vērtībai, zvaniet uz Nākamais metode Ģeneratora objektā.

Piemēram:

konst gen = piemērs();

console.log (gen.next()); // { vērtība: "Ģenerators", darīts: taisnība }

Iepriekš minētajā piemērā vērtību īpašums nāca no a atgriezties atslēgvārdu, efektīvi pārtraucot ģeneratora darbību. Šāda rīcība parasti ir nevēlama, izmantojot ģeneratora funkcijas, jo tās atšķir no parastajām funkcijām spēja apturēt un restartēt izpildi.

Ienesīguma atslēgvārds

The raža atslēgvārds nodrošina veidu, kā atkārtot vērtības ģeneratoros, apturot ģeneratora funkcijas izpildi un atgriežot tai sekojošo vērtību.

Piemēram:

funkciju* piemērs() {
raža"Modelis S"
raža"Modelis X"
raža"Kiber kravas automašīna"

atgriezties"Tesla"
}

konst gen = piemērs();

console.log (gen.next()); // { vērtība: "Model S", darīts: viltus }

Iepriekš minētajā piemērā, kad Nākamais metode tiek izsaukta piemērs ģenerators, tas apstāsies ikreiz, kad saskarsies ar raža atslēgvārds. The darīts īpašums tiks iestatīts arī uz viltus līdz tas saskaras ar a atgriezties atslēgvārds.

Zvanot uz Nākamais metode vairākas reizes uz piemērs ģeneratoru, lai to parādītu, jums būs šāda izvade.

console.log (gen.next()); // { vērtība: "Modelis X", darīts: viltus }
console.log (gen.next()); // { vērtība: "Kiberkravas automašīna", darīts: viltus }
console.log (gen.next()); // { vērtība: "Tesla", darīts: taisnība }

konsole.log (gen.next()); // { value: undefined, done: true }

Varat arī atkārtot ģeneratora objektu, izmantojot par...no cilpa.

Piemēram:

priekš (konst iterators no gen) {
konsole.log (iterators);
}

/*
Modelis S
Modelis X
Kiber kravas automašīna
*/

Iteratoru un ģeneratoru izmantošana

Lai gan iteratori un ģeneratori var šķist abstrakti jēdzieni, tie tā nav. Tie var būt noderīgi, strādājot ar bezgalīgām datu plūsmām un datu kolekcijām. Varat arī tos izmantot, lai izveidotu unikālus identifikatorus. Valsts pārvaldības bibliotēkas, piemēram, MobX-State-Tree (MST), arī tās izmanto zem pārsega.