Afmystificering af ES6 Iterables & Iterators

ES6 introducerer en ny måde at interagere med JavaScript datastrukturer - iteration . Lad os afmystificere det.

Der er to kernekoncepter:

  • Iterabel - beskrevet af en datastruktur, der giver en måde at udsætte sine data for offentligheden på. Dette gøres ved at implementere en metode, hvis nøgle er Symbol.iterator. Symbol.iteratorer en fabrik af iteratorer.
  • Iterator - beskrevet af en struktur, der indeholder en markør til det næste element i iteration.

Protokol

Både iterable og iterator følger en protokol, der gør det muligt for objekter at blive iterable:

  • En interabel skal være et objekt med en funktionsiterator, hvis nøgle er Symbol.iterator.
  • En iterator skal være et objekt med en funktion med navnet, nextder returnerer et objekt med tasterne: value- det aktuelle element i iteration; og done- sandt, hvis iteration er afsluttet, ellers falsk .

Iterabilitet

Iterabilitet følger ideen om datakilder og dataforbrugere :

  • datakilder - er det sted, hvorfra forbrugerne får deres data. For eksempel er en Arraysådan som [1,2,3]en datakildestruktur, der indeholder de data, gennem hvilke en dataforbruger vil gentage (f.eks. 1, 2, and 3). Flere eksempler er String, Mapsog Sets.
  • dataforbrugere - er det, der forbruger data fra datakilder. For eksempel er for-ofsløjfen en dataforbruger, der er i stand til at gentage over en Arraydatakilde. Flere eksempler er spread operatorog Array.from.

For at en struktur skal være en datakilde , skal den tillade og sige, hvordan dens data skal forbruges. Dette gøres gennem iteratorer . Derfor skal en datakilde følge iteratorprotokollen beskrevet ovenfor.

Det er dog ikke praktisk for enhver dataforbruger at understøtte alle datakilder , især da JavaScript giver os mulighed for at opbygge vores egne datakilder. Så ES6 introducerer grænsefladen Iterable .

Dataforbrugere bruger data fra datakilder gennem iterables .

I praksis

Lad os se, hvordan dette fungerer på en defineret datakilde - Array.

Iterable datakilder

Vi bruger for-oftil at udforske nogle af de datakilder, der implementerer den iterable protokol .

Almindelige genstande

På dette stadium er vi nødt til at sige, at almindelige objekter ikke kan gentages. Axel Rauschmayer gør et godt stykke arbejde med at forklare hvorfor på at udforske ES6.

En kort forklaring er, at vi kan gentage et JavaScript-objekt på to forskellige niveauer:

  • programniveau - hvilket betyder iterering over et objektegenskaber, der repræsenterer dets struktur. For eksempel, Array.prototype.lengthhvor lengther relateret til objektets struktur og ikke dets data.
  • data niveau - hvilket betyder, iteration over en datastruktur og udtrække sine data. For eksempel betyder det for vores Arrayeksempel, at det gentager sig over arrayets data. Hvis array = [1,2,3,4], gentag værdierne 1, 2, 3 and 4.
At bringe begrebet iteration i almindelige objekter betyder imidlertid blandingsprogram og datastrukturer - Axel

Problemet med almindelige objekter er alles evne til at skabe deres egne objekter.

I vores Hugos eksempel hvordan ville JavaScript skelne mellem de data niveau, dvs. Hugo.fullName, og programmet niveau, dvs. Hugo.toString()?

Selvom det er muligt at skelne mellem de to niveauer af iteration på veldefinerede strukturer, såsom Arrays, er det umuligt at gøre det for noget objekt.

Det er derfor, vi får iteration gratis på Array(også på String, Mapog Set), men ikke på almindeligt objekter.

Vi kan dog implementere vores egne iterables.

Implementere Iterables

Vi kan bygge vores egne iterables, selvom vi normalt bruger generatorer til det.

For at opbygge vores egen iterable skal vi følge iterationsprotokollen, der siger:

  • Et objekt bliver en iterabel, hvis det implementerer en funktion, hvis nøgle er Symbol.iteratorog returnerer en iterator.
  • Det iteratori sig selv er et objekt med en funktion kaldet nextinde i det. nextskal returnere et objekt med to taster valueog done. valueindeholder det næste element i iteration og doneet flag, der siger, om iteration er afsluttet.

Eksempel

Vores gentagne implementering er meget enkel. Vi har fulgt den iterable protokol, og på hver iteration vil for-ofsløjfen bede iteratoren om nextelementet.

Vores iterator vender tilbage på nextet objekt, der indeholder følgende ved iteration:

Bemærk, at vi skifter rækkefølgen af ​​vores ejendomme nextog donefor nemheds skyld. Under nextførste, ville det bryde gennemførelsen siden vi først vil poppe et element, og derefter tælle elementerne.

Det er nyttigt at vide, at det doneer falsesom standard, hvilket betyder, at vi kan ignorere det, når det er tilfældet. Det samme gælder for valuehvornår doneer true.

Det ser vi om et øjeblik.

Iterator som en Iterabel

Vi kunne bygge vores iterator som en iterabel.

Bemærk, at dette er mønsteret efterfulgt af ES6 indbyggede iteratorer.

Hvorfor er dette nyttigt?

Selvom det for-ofkun fungerer med iterables, ikke med iterators, betyder det at være det samme, at vi kan stoppe udførelsen af for-ofog fortsætte efterord.

Retur og kast

Der er to valgfri iteratormetoder, som vi endnu ikke har undersøgt:

Vend tilbage

returngiver iteratoren mulighed for at rydde op i huset, når det uventet går i stykker. Når vi ringer returntil en iterator, specificerer vi, at vi ikke planlægger at ringe nextlængere.

Kaste

throwgælder kun for generatorer. Det vil vi se, når vi leger med generatorer.

Konklusion

ES6 bringer iteration som en ny måde at gentage JavaScript-datastrukturer på.

For at iteration er mulig er der dataproducenter , der indeholder dataene, og dataforbrugere, der tager disse data.

For at denne kombination skal fungere problemfrit, er iteration defineret af en protokol, der siger:

  • An iterableer et objekt, der implementerer en funktion, hvis nøgle er Symbol.iteratorog returnerer en iterator.
  • En iteratorer et objekt med en funktion kaldet nextinde i det. nexter et objekt med to taster valueog done. valueindeholder det næste element i iteration og doneet flag, der siger, om iteration er afsluttet.

Almindelige objekter er ikke, iterableda der ikke er nogen nem måde at skelne mellem program- og dataniveau-iteration.

Derfor tilbyder ES6 en måde at opbygge vores egne iteratorer på ved at følge iteratorprotokollen.

Tak til ?

  • Axel Rauschmayer for hans Exploring ES6 - Iteration
  • Nicolás Bevacqua for hans PonyFoo - ES6 Iteratorer i dybden
  • Til alle The Simpsons fans

Sørg for at tjekke mine andre artikler om ES6

Lad os udforske ES6-generatorer

Generatorer er en implementering af iterables. medium.freecodecamp.com