Kysy konsultilta: Mitä ovat generaattorit JavaScriptissä?

lokak. 25, 2023

Mitä ovat generaattorit JavaScriptissä?

Generaattorit yleisesti


Generaattorit ovat yleinen ohjelmointikielten ominaisuus. Esimerkiksi JavaScript, Python, Java, C++ ja PHP tukevat generaattoreita. Generaattorit tarjoavat yleisen ja suhteellisen helpon tavan toteuttaa iteraattorirajapinta, joka kykenee käymään läpi, siis iteroimaan datasarjan alkiot. Sarja voi olla rajallinen, mutta myös virtuaalisesti loputon.


Generaattoreita voidaan käyttää esimerkiksi listan läpikäyntiin yksi alkio kerrallaan, suorittaa välissä muuta koodia ja palata sitten tarpeen mukaan alkioiden käsittelyyn siitä kohdasta, johon viimeksi jäätiin. Tämä on hyödyllistä esimerkiksi silloin, kun alkioiden käsittely kerralla kuluttaisi liikaa muistia, tai silloin, kun vasta alkiota käsiteltäessä ratkeaa halutaanko listan iterointia ylipäätään jatkaa.


Generaattorit JavaScriptissä


JavaScriptissä generaattorifunktio tarjoaa mahdollisuuden kirjoittaa iteratiivinen algoritmi helposti funktion muodossa. Generaattorifunktion iteratiivisen osan suoritusta ei kuitenkaan aloiteta vielä generaattorin luontivaiheessa. Iterointikierroksia suoritetaan erikseen kutsumalla generaattorifunktion palauttaman generaattorin next()-metodia.


Generaattorifunktio määritetään merkitsemällä tähti function-sanan ja funktion nimen väliin. Tähden on oltava heti function-sanan perässä mikäli kyseessä on anonyymi generaattorifunktio.

Generaattorifunktio palauttaa iteroitavan iteraattoriobjektin (engl. iterable iterator), joka täyttää kaikki iteroitavan objektin vaatimukset. Huomaa, että “iterable” on eri asia kuin “iterator”, ja että molemmat ominaisuudet tarvitaan oikeaoppisen iteraattorin toteuttamiseen.


Generaattorifunktion sisään kirjoitetaan tyypillisesti yksi tai useampia yield-ilmauksia, jotka toimivat kuin return-ilmaukset sillä erotuksella, että yield-palautuksen jälkeen iteraattori muistaa sen tilan, eli funktion sisäisessä skoopissa määriteltyjen muuttujien arvot, johon se viime suorituskerralla jäi. Vaikka yield-ilmauksia olisi vain yksi, se voi palauttaa arvoja useita kertoja esimerkiksi toistorakenteen sisällä.


Merkitsemällä yield-ilmauksen perään tähtimerkintä (yield*) voidaan iteraattorin palauttama arvo halutessa delegoida toiselle iteroitavalle objektille.

Iteraattorit JavaScriptissä


Alla on esimerkki JavaScript-iteraattorin toteutuksesta. For..of-rakenne osaa käyttää mitä tahansa iteroitavaa objektia. JavaScriptissä on useita natiiveja iteroitavia objekteja kuten Array-, String- tai Map-rakenteiden instanssit. 



Myös Generaattorifunktion palauttama generaattori on iteroitava objekti, jota for..of-rakenne osaa iteroida. Alla olevassa esimerkissä ei ole genraattoria eikä generaattorifunktiota, vaan iteroitava iteraattoriobjekti manuaalisesti luotuna. Generaattorifunktiot ovat apuvälineitä, joiden ansiosta meidän ei tarvitse luoda iteroitavia iteraattoreita alusta asti, koska generaattorifunktio palauttaa meille sellaisen.


Mistä tahansa objektista saadaan iteroitava (engl. iterable), kun objektilla on oikeaoppisesti toteutettu next()-metodi. Objektista tulee kuitenkin iteraattori, kun sillä on myös @@iterator-metodi.


Huom: @@-etuliite on tapa merkitä JavaScript -symboleita. Esimerkiksi Symbol.iterator voidaan merkitä @@iterator.


Yhteenveto


JavaScriptissä generaattorifunktioita käytetään luomaan generaattoreita, jotka ovat iteroitavia iteraattoreita samoin kuin monet muut JavaScript-rakenteet (esim. String- tai Array-rakenteiden instanssit). Generaattorifunktion sisällä yield-ilmaus palauttaa iteraatiokierroksen arvon, mutta yield*-ilmauksella palautus voidaan delegoida myös muulle iteroitavalle objektille. Objekti on iteraattori mikäli se toteuttaa oikeaoppisen next()-metodin. Objekti on lisäksi iteroituva, mikäli se toteuttaa oikeaoppisesti myös @@iterator-metodin.

Johan Stenroth

Consultant

Viimeisimmät kirjoitukset

Webscalen konsultteja.
03 May, 2024
Kysy konsultilta -blogisarjassa konsulttimme tekevät selkoa alan termeistä ja ilmiöistä. Vastaukset on mitoitettu sopimaan pieneenkin tiedonnälkään. Tällä kertaa selvitämme, miten FinOps auttaa pilvikustannuksissa?
Webscalen konsultteja.
26 Apr, 2024
Kysy konsultilta -blogisarjassa konsulttimme tekevät selkoa alan termeistä ja ilmiöistä. Vastaukset on mitoitettu sopimaan pieneenkin tiedonnälkään. Tällä kertaa selvitämme, mikä on AWS Landing Zone?
Webscalen konsultteja.
19 Apr, 2024
Kysy konsultilta -blogisarjassa konsulttimme tekevät selkoa alan termeistä ja ilmiöistä. Vastaukset on mitoitettu sopimaan pieneenkin tiedonnälkään. Tällä kertaa selvitämme, mitä on DevSecOps?
Webscalen konsultteja.
12 Apr, 2024
Kysy konsultilta -blogisarjassa konsulttimme tekevät selkoa alan termeistä ja ilmiöistä. Vastaukset on mitoitettu sopimaan pieneenkin tiedonnälkään. Tällä kertaa selvitämme, mikä on Serverless Framework?
Lisää kirjoituksia
Share by: