10. Destrukturering

10. Destrukturering #

  • 10.1. Oversikt
    • 10.1.1. Objektdestrukturering
    • 10.1.2. Array destrukturering
    • 10.1.3. Hvor kan destrukturering brukes?
  • 10.2. Bakgrunn: Konstruere data versus trekke ut data
  • 10.3. Mønstre for destrukturering
    • 10.3.1. Velg det du trenger
  • 10.4. Hvordan får mønstre tilgang til verdiene?
    • 10.4.1. Objektmønstre tvinger verdier til objekter
    • 10.4.2. Array mønstre arbeide med iterables
  • 10.5. Standardverdier
    • 10.5.1. undefined utløser standardverdier
    • 10.5.2. Standardverdier beregnes ved behov
    • 10.5.3. Standardverdier kan referere til andre variabler i mønsteret
    • 10.5.4. Standardverdier for mønstre
    • 10.5.5. Mer komplekse standardverdier
  • 10.6. Flere objekt destrukturering funksjoner
    • 10.6.1. Egenskapsverdi shorthands
    • 10.6.2. Beregnede eiendomsnøkler
  • 10.7. Flere Array destrukturering funksjoner
    • 10.7.1. Elision
    • 10.7.2. Rest operatør (...)
  • 10.8. Du kan tilordne til mer enn bare variabler
  • 10.9. Fallgruver av destrukturering
    • 10.9.1. Ikke start en uttalelse med en krøllete spenne
  • 10.10. Eksempler på destrukturering
    • 10.10.1. Destrukturering returnerte Arrays
    • 10.10.2. Destrukturering returnerte objekter
    • 10.10.3. Array-destrukturering iterable verdier
    • 10.10.4. Flere returverdier
  • 10.11. Destruktureringsalgoritmen
    • 10.11.1. Algoritmen
    • 10.11.2. Bruk av algoritmen

10.1 Oversikt #

Destrukturering er en praktisk måte å trekke ut flere verdier fra data lagret i (muligens nestede) objekter og Arrays. Den kan brukes på steder som mottar data (for eksempel på venstre side av en oppgave). Hvordan trekke ut verdiene er spesifisert via mønstre (les videre for eksempler).

10.1.1 objektdestrukturering #

Destrukturering av objekter:

const obj = { first: 'Jane', last: 'Doe' };const {first: f, last: l} = obj; // f = 'Jane'; l = 'Doe'// {prop} is short for {prop: prop}const {first, last} = obj; // first = 'Jane'; last = 'Doe'

Destrukturering hjelper med å behandle returverdier:

const obj = { foo: 123 };const {writable, configurable} = Object.getOwnPropertyDescriptor(obj, 'foo');console.log(writable, configurable); // true true

10.1.2 Array destrukturering #

Array destrukturering (fungerer for alle iterable verdier):

const iterable = ;const  = iterable; // x = 'a'; y = 'b'

Destrukturering hjelper med å behandle returverdier:

const  = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ .exec('2999-12-31');

10.1.3 Hvor kan destrukturering brukes? #

Destrukturering kan brukes på følgende steder (jeg viser Matrisemønstre for å demonstrere; objektmønstre fungerer like bra):

// Variable declarations:const  = ;let  = ;var  = ;// Assignments: = ;// Parameter definitions:function f() { ··· }f();

du kan også ødelegge i en for-of loop:

const arr = ;for (const  of arr.entries()) { console.log(index, element);}// Output:// 0 a// 1 b

10.2 Bakgrunn: Konstruksjon av data versus utpakking av data #

for å forstå hva destrukturering er, la oss først undersøke den bredere konteksten.

JavaScript har operasjoner for å bygge data, en egenskap om gangen:

const obj = {};obj.first = 'Jane';obj.last = 'Doe';

den samme syntaksen kan brukes til å trekke ut data. Igjen, en eiendom om gangen:

const f = obj.first;const l = obj.last;

I Tillegg er det syntaks for å konstruere flere egenskaper samtidig, via et objekt bokstavelig:

const obj = { first: 'Jane', last: 'Doe' };

FØR ES6 var det ingen tilsvarende mekanisme for utvinning av data. Det er hva destrukturering er – det lar deg trekke ut flere egenskaper fra et objekt via et objektmønster. For eksempel på venstre side av en oppgave:

const { first: f, last: l } = obj;

du kan også ødelegge Arrays via mønstre:

const  = ; // x = 'a'; y = 'b'

10.3 mønstre for destrukturering #

følgende to parter er involvert i destrukturering:

  • Destruktureringskilde: dataene som skal destrueres. For eksempel, høyre side av en destruktureringsoppgave.
  • Destruktureringsmål: mønsteret som brukes til destrukturering. For eksempel, venstre side av en destruktureringsoppgave.

destruktureringsmålet er enten ett av tre mønstre:

  • Oppdragsmål. For eksempel: x
    • et oppgavemål er vanligvis en variabel. Men i destruksjonsoppdrag har du flere alternativer, som jeg vil forklare senere.
  • Objekt mønster. For eksempel: { first: "pattern", last: "pattern" }
    • delene av et objektmønster er egenskaper, egenskapsverdiene er igjen mønstre (rekursivt).
  • Array mønster. For eksempel:
    • delene av Et Matrisemønster er elementer, elementene er igjen mønstre (rekursivt).

Det betyr at du kan hekke mønstre, vilkårlig dypt:

const obj = { a: , b: true };const { a:  } = obj; // f = 123

10.3.1 Velg hva du trenger #

hvis du ødelegger et objekt, nevner du bare de egenskapene du er interessert i:

const { x: x } = { x: 7, y: 3 }; // x = 7

hvis du ødelegger En Matrise, kan du velge å bare trekke ut et prefiks:

const  = ; // x='a'; y='b';

10.4 Hvordan får mønstre tilgang til verdiene? #

i en oppgave pattern = someValue, hvordan får pattern tilgang til hva som er inni someValue?

10.4.1 Objektmønstre tvinger verdier til objekter #

objektmønsteret tvinger destruktureringskilder til objekter før de får tilgang til egenskaper. Det betyr at det fungerer med primitive verdier:

const {length : len} = 'abc'; // len = 3const {toString: s} = 123; // s = Number.prototype.toString
10.4.1.1 Unnlatelse av objektdestruksjon en verdi #

tvangen til objekt utføres ikke via Object(), men via den interne operasjonen ToObject(). De to operasjonene håndterer undefined og null forskjellig.

Object() konverterer primitive verdier til wrapper objekter og etterlater objekter urørt:

> typeof Object('abc')'object'> var obj = {};> Object(obj) === objtrue

It also converts undefined and null to empty objects:

> Object(undefined){}> Object(null){}

In contrast, ToObject() throws a TypeError if it encounters undefined or null. Therefore, the following destructurings fail, even before destructuring accesses any properties:

const { prop: x } = undefined; // TypeErrorconst { prop: y } = null; // TypeError

som en konsekvens kan du bruke det tomme objektmønsteret {} for å sjekke om en verdi er tvunget til et objekt. Som vi har sett, er det bare undefined og null ikke:

({} = ); // OK, Arrays are coercible to objects({} = 'abc'); // OK, strings are coercible to objects({} = undefined); // TypeError({} = null); // TypeError

parentesene rundt uttrykkene er nødvendige fordi setninger ikke må begynne med krøllete braces I JavaScript (detaljer forklares senere).

10.4.2 Array patterns arbeid med iterables #

Array destrukturering bruker en iterator for å komme til elementene i en kilde. Derfor Kan Du Array-destructure noen verdi som er iterable. La oss se på eksempler på iterable verdier.

Strenger er iterable:

const  = 'abc'; // x='a'; y=

Ikke glem at iteratoren over strenger returnerer kodepunkter («Unicode-tegn», 21 biter), ikke kodeenheter («JavaScript-tegn», 16 biter). (For mer informasjon Om Unicode, se kapittelet » Kapittel 24. Unicode Og JavaScript » I «Snakker JavaScript».) For eksempel:

const  = 'a\uD83D\uDCA9c'; // x='a'; y='\uD83D\uDCA9'; z='c'

du kan ikke få tilgang til elementene i Et Sett via indekser, men du kan gjøre det via en iterator. Derfor Fungerer Matrisestrukturering for Sett:

const  = new Set(); // x='a'; y='b';

Set iteratoren returnerer alltid elementer i den rekkefølgen de ble satt inn, og derfor er resultatet av den forrige destruktureringen alltid den samme.

10.4.2.1 Unnlater Å Array-destructure en verdi #

en verdi er iterable hvis den har en metode hvis nøkkelen er Symbol.iterator som returnerer et objekt. Array-destrukturering kaster en TypeError hvis verdien som skal ødelegges, ikke er iterbar:

let x; = ; // OK, Arrays are iterable = 'abc'; // OK, strings are iterable = { * () { yield 1 } }; // OK, iterable = {}; // TypeError, empty objects are not iterable = undefined; // TypeError, not iterable = null; // TypeError, not iterable

TypeError kastes selv før du får tilgang til elementer av iterable, noe som betyr at du kan bruke det tomme Matrisemønsteret for å sjekke om en verdi er iterbar:

 = {}; // TypeError, empty objects are not iterable = undefined; // TypeError, not iterable = null; // TypeError, not iterable

10.5 Standardverdier #

Standardverdier er en valgfri funksjon i mønstre. De gir et fallback hvis ingenting er funnet i kilden. Hvis en del (en objektegenskap eller Et Matriseelement) ikke har samsvar i kilden, matches den mot:

  • standardverdien (hvis angitt; det er valgfritt)
  • undefined (ellers)

La oss se på et eksempel. I følgende destrukturering har elementet ved indeks 0 ingen match på høyre side. Derfor fortsetter destrukturering ved å matche x mot 3, noe som fører til at x blir satt til 3.

const  = ; // x = 3; y = undefined

du kan også bruke standardverdier i objektmønstre:

const {foo: x=3, bar: y} = {}; // x = 3; y = undefined

10.5.1 undefined utløser standardverdier #

Standardverdier brukes også hvis en del har en kamp og at kampen er undefined:

const  = ; // x = 1const {prop: y=2} = {prop: undefined}; // y = 2

begrunnelsen for denne virkemåten er forklart i neste kapittel, i delen om standardverdier for parametere.

10.5.2 Standardverdier beregnes på forespørsel #

standardverdiene selv beregnes bare når de trengs. Med andre ord, denne ødeleggelsen:

const {prop: y=someFunc()} = someValue;

er ekvivalent med:

let y;if (someValue.prop === undefined) { y = someFunc();} else { y = someValue.prop;}

du kan observere at hvis du bruker console.log():

> function log(x) { console.log(x); return 'YES' }> const = ;> a'YES'> const = ;> b123

In the second destructuring, the default value is not triggered and log() is not called.

10.5.3 Default values can refer to other variables in the pattern #

A default value can refer to any variable, including other variables in the same pattern:

const  = ; // x=3; y=3const  = ; // x=7; y=7const  = ; // x=7; y=2

men ordre saker: variablene x og y deklareres fra venstre til høyre og produserer en ReferenceError hvis de åpnes før deklarasjonene:

const  = ; // ReferenceError

10.5.4 Standardverdier for mønstre #

Så langt har vi bare sett standardverdier for variabler, men du kan også knytte dem til mønstre:

const  = ;

Hva betyr dette? Husk regelen for standardverdier: hvis en del ikke har samsvar i kilden, fortsetter destruktureringen med standardverdien.

elementet ved indeks 0 har ingen match, og derfor fortsetter destruktureringen med:

const { prop: x } = {}; // x = undefined

du kan lettere se hvorfor ting fungerer på denne måten hvis du erstatter mønsteret { prop: x } med variabelen pattern:

const  = ;

10.5.5 mer komplekse standardverdier #

la oss videre utforske standardverdier for mønstre. I følgende eksempel tilordner vi en verdi til x via standardverdien { prop: 123 }:

const  = ;

Fordi Matriseelementet ved indeks 0 ikke har samsvar på høyre side, fortsetter destruktureringen som følger og x er satt til 123.

const { prop: x } = { prop: 123 }; // x = 123

x tilordnes Imidlertid ikke en verdi på denne måten hvis høyre side har et element ved indeks 0, fordi standardverdien ikke utløses.

const  = ;

i dette tilfellet fortsetter destrukturering med:

const { prop: x } = {}; // x = undefined

Dermed, Hvis du vil x å være 123 hvis enten objektet eller egenskapen mangler, må du angi en standardverdi for x selv:

const  = ;

her fortsetter destruktureringen som følger, uavhengig av om høyre side er eller .

const { prop: x=123 } = {}; // x = 123

10.6 Flere funksjoner for objektdestrukturering #

10.6.1 Egenskapsverdi shorthands #

Egenskapsverdi shorthands er en funksjon av objektlitteraler: Hvis egenskapsverdien er en variabel som har samme navn som egenskapsnøkkelen, kan du utelate nøkkelen. Dette fungerer for destrukturering, også:

const { x, y } = { x: 11, y: 8 }; // x = 11; y = 8// Same as:const { x: x, y: y } = { x: 11, y: 8 };

Du kan også kombinere egenskapsverdi shorthands med standardverdier:

const { x, y = 1 } = {}; // x = undefined; y = 1

10.6.2 Beregnede eiendomsnøkler #

Beregnede eiendomsnøkler er en annen objekt bokstavelig funksjon som også fungerer for destrukturering. Du kan angi nøkkelen til en egenskap via et uttrykk, hvis du setter det i hakeparenteser:

const FOO = 'foo';const { : f } = { foo: 123 }; // f = 123

Beregnede eiendomsnøkler lar deg ødelegge egenskaper hvis nøkler er symboler:

// Create and destructure a property whose key is a symbolconst KEY = Symbol();const obj = { : 'abc' };const { : x } = obj; // x = 'abc'// Extract Array.prototypeconst { : func } = ;console.log(typeof func); // function

10.7 Flere array destruktureringsfunksjoner #

10.7.1 Elision #

Elision lar deg bruke syntaksen Til Array «hull» for å hoppe over elementer under destrukturering:

const  = ; // x = 'c'; y = 'd'

10.7.2 Rest operatør (...) #

resten operatoren lar deg trekke ut de resterende elementene i en iterable i En Matrise. Hvis denne operatøren brukes inne I Et Matrisemønster, må det komme sist:

const  = ; // x='a'; y=

hvis operatøren ikke finner noen elementer, samsvarer den med operand mot det tomme Arrayet. Det vil si at det aldri produserer undefined eller null. For eksempel:

const  = ; // x='a'; y=undefined; z=

operanden til resten operatøren trenger ikke å være en variabel, du kan også bruke mønstre:

const ] = ; // x = 'a'; y = 'b'; z = 'c'

resten operatøren utløser følgende destrukturering:

 = 

10.8 du kan tilordne til mer enn bare variabler #

hvis du tilordner via destrukturering, kan hvert oppdragsmål være alt som er tillatt på venstre side av en vanlig oppgave.

for eksempel en referanse til en egenskap (obj.prop):

const obj = {};({ foo: obj.prop } = { foo: 123 });console.log(obj); // {prop:123}

eller en referanse til Et Matriseelement (arr):

const arr = ;({ bar: arr } = { bar: true });console.log(arr); // 

du kan også tilordne objektegenskaper og Matriseelementer via rest-operatoren (...):

const obj = {}; = ; // first = 'a'; obj.prop = 

hvis du deklarerer variabler eller definerer parametere via destrukturering, må du bruke enkle identifikatorer, du kan ikke referere til objektegenskaper og Arrayelementer.

10.9 Fallgruver av destrukturering #

det er to ting å være oppmerksom på når du bruker destrukturering:

  • du kan ikke starte en uttalelse med en krøllete spenne.
  • under destrukturering kan du enten deklarere variabler eller tilordne dem, men ikke begge.

de neste to delene inneholder detaljene.

10.9.1 ikke start en setning med en krøllete spenne #

fordi kodeblokker begynner med en krøllete spenne, må setninger ikke begynne med en. Dette er uheldig når du bruker objektdestrukturering i en oppgave:

{ a, b } = someObject; // SyntaxError

arbeidet er å sette hele uttrykket i parentes:

({ a, b } = someObject); // OK

følgende syntaks virker ikke:

({ a, b }) = someObject; // SyntaxError

med let, var og const forårsaker ikke klammeparenteser problemer:

const { a, b } = someObject; // OK

10.10 Eksempler på destrukturering #

La oss starte med noen mindre eksempler.

sløyfen for-of støtter destrukturering:

const map = new Map().set(false, 'no').set(true, 'yes');for (const  of map) { console.log(key + ' is ' + value);}

du kan bruke destrukturering til å bytte verdier. Det er noe som motorer kunne optimalisere, slik at Ingen Matrise ville bli opprettet.

 = ;

du kan bruke destrukturering til å dele En Matrise:

const  = ; // first = 'a'; rest = 

10.10.1 Destrukturering returnerte Arrays #

noen innebygde JavaScript-operasjoner returnerer Arrays. Destrukturering hjelper med å behandle dem:

const  = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ .exec('2999-12-31');

hvis du bare er interessert i gruppene (og ikke i hele kampen, all), kan du bruke elision til å hoppe over matriseelementet på indeks 0:

const  = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ .exec('2999-12-31');

exec() returnerer null hvis det regulære uttrykket ikke samsvarer. Dessverre kan du ikke håndtere null via standardverdier, og derfor må Du bruke or-operatøren (||) i dette tilfellet:

const  = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ .exec(someStr) || ;

Array.prototype.split() returnerer En Matrise. Derfor er destrukturering nyttig hvis du er interessert i elementene, ikke Matrisen:

const cells = 'Jane\tDoe\tCTO'const  = cells.split('\t');console.log(firstName, lastName, title);

10.10.2 Destrukturering returnerte objekter #

Destrukturering er også nyttig for å trekke ut data fra objekter som returneres av funksjoner eller metoder. Iteratormetoden next() returnerer for eksempel et objekt med to egenskaper, done og value. Følgende kode logger alle elementene I Array arr via iteratoren iter. Destrukturering brukes i linje A.

const arr = ;const iter = arr();while (true) { const {done,value} = iter.next(); // (A) if (done) break; console.log(value);}

10.10.3 Array-destrukturering iterable verdier #

Array-destrukturering fungerer med en iterbar verdi. Det er noen ganger nyttig:

const  = new Set().add('a').add('b'); // x = 'a'; y = 'b'const  = 'foo'; // a = 'f'; b = 'o'

10.10.4 Flere returverdier #

for å se nytten av flere returverdier, la oss implementere en funksjon findElement(a, p) som søker etter det første elementet i Matrisen a som funksjonen p returnerer true. Spørsmålet er: hva skal findElement() returnere? Noen ganger er man interessert i selve elementet, noen ganger i indeksen, noen ganger i begge deler. Følgende implementering returnerer begge.

function findElement(array, predicate) { for (const  of array.entries()) { // (A) if (predicate(element, index, array)) { // We found an element: return { element, index }; // Same as (property value shorthands): // { element: element, index: index } } } // We couldn't find anything; return failure values: return { element: undefined, index: -1 };}

funksjonen itererer over alle elementer av array, via Array-metoden entries(), som returnerer en iterbar over par (linje A). Delene av parene er tilgjengelige via destrukturering.

La oss bruke findElement():

const arr = ;const {element, index} = findElement(arr, x => x % 2 === 0); // element = 8, index = 1

Flere ECMAScript 6 funksjoner tillatt oss å skrive mer konsis kode: tilbakeringing er en pil funksjon; returverdien ødelegges via et objekt mønster med egenskapsverdi shorthands.

På grunn av index og element refererer også til eiendomsnøkler, rekkefølgen der vi nevner dem, spiller ingen rolle. Vi kan bytte dem og ingenting endres:

const {index, element} = findElement(···);

Vi har lykkes med å håndtere saken om å trenge både indeks og element. Hva om vi bare er interessert i en av dem? Det viser seg at, takket Være ECMAScript 6, kan implementeringen vår også ta vare på det. Og syntaktisk overhead sammenlignet med funksjoner med enkelt returverdier er minimal.

const a = ;const {element} = findElement(a, x => x % 2 === 0); // element = 8const {index} = findElement(a, x => x % 2 === 0); // index = 1

Hver gang trekker vi bare ut verdien av den ene egenskapen vi trenger.

10.11 destruktureringsalgoritmen #

denne delen ser på destrukturering fra en annen vinkel: som en rekursiv mønstermatching algoritme.

på slutten bruker jeg algoritmen til å forklare forskjellen mellom de følgende to funksjonsdeklarasjonene.

function move({x=0, y=0} = {}) { ··· }function move({x, y} = { x: 0, y: 0 }) { ··· }

10.11.1 algoritmen #

en destruktureringsoppgave ser slik ut:

"pattern" = "value"

vi vil bruke pattern for å trekke ut data fra value. Jeg skal nå beskrive en algoritme for å gjøre det, som er kjent i funksjonell programmering som mønstermatching (kort: matching). Algoritmen spesifiserer operatøren («kamp mot») for destruktureringsoppgave som samsvarer med en pattern mot en value og tilordner variabler mens du gjør det:

"pattern"  "value"

algoritmen er spesifisert via rekursive regler som tar fra hverandre begge operandene til operatoren . Den deklarative notasjonen kan ta litt vant til, men det gjør spesifikasjonen av algoritmen mer konsis. Hver regel har to deler:

  • hodet (første linje) beskriver tilstanden som utløser regelen.
  • brødteksten (gjenværende linjer) beskriver hva som skjer hvis regelen utløses.

La oss se på et eksempel:

  • (2c) {key: "pattern", "properties"} ← obj
     "pattern"  obj.key {"properties"}  obj
  • (2e) {} ← obj(ingen egenskaper igjen)
     // Nothing to do

i regel (2c) betyr hodet at denne regelen utføres hvis det er et objektmønster med minst en egenskap og null eller flere gjenværende egenskaper. Dette mønsteret matches mot en verdi obj. Effekten av denne regelen er at utførelsen fortsetter med egenskapsverdimønsteret blir matchet mot obj.key og de resterende egenskapene blir matchet mot obj.

i regel (2e) betyr hodet at denne regelen utføres hvis det tomme objektmønsteret {} matches mot en verdi obj. Da er det ingenting å gjøre.

når algoritmen påberopes, kontrolleres reglene fra topp til bunn, og bare den første regelen som gjelder, utføres.

jeg viser bare algoritmen for destruktureringsoppgave. Variable deklarasjoner og parameterdefinisjoner for destrukturering fungerer på samme måte.

jeg dekker ikke avanserte funksjoner( beregnede egenskapsnøkler; egenskapsverdi shorthands; objektegenskaper og matriseelementer som tildelingsmål), enten. Bare det grunnleggende.

10.11.1.1 Mønstre #

et mønster er enten:

  • en variabel: x
  • et objektmønster: {"properties"}
  • Et Matrisemønster:

hver av de følgende avsnittene beskriver en av disse tre tilfellene.

de følgende tre delene angir hvordan disse tre sakene skal håndteres. Hver seksjon inneholder en eller flere nummererte regler.

10.11.1.2 Variabel #
  • (1) x ← value (inkludert undefined og null)
     x = value
10.11.1.3 Objekt mønster #
  • (2a) {"properties"} ← undefined
     throw new TypeError();
  • (2b) {"properties"} ← null
     throw new TypeError();
  • (2c) {key: "pattern", "properties"} ← obj
     "pattern"  obj.key {"properties"}  obj
  • (2d) {key: "pattern" = default_value, "properties"} ← obj
     const tmp = obj.key; if (tmp !== undefined) { "pattern"  tmp } else { "pattern"  default_value } {"properties"}  obj
  • (2e) {} ← obj(ingen egenskaper igjen)
     // Nothing to do
10.11.1.4 Matrisemønster #

Matrisemønster og iterable. Algoritmen for Array destrukturering starter med Et Array mønster og en iterable:

  • (3a) ← non_iterable
    assert(!isIterable(non_iterable))
     throw new TypeError();
  • (3b) ← iterable
    assert(isIterable(iterable))
     const iterator = iterable(); "elements"  iterator

Helper funksjon:

function isIterable(value) { return (value !== null && typeof value === 'object' && typeof value === 'function');}

Array elementer og iterator. Algoritmen fortsetter med elementene i mønsteret (venstre side av pilen) og iteratoren som ble oppnådd fra iterable (høyre side av pilen).

  • (3c) "pattern", "elements" ← iterator
     "pattern"  getNext(iterator) // undefined after last item "elements"  iterator
  • (3d) "pattern" = default_value, "elements" ← iterator
     const tmp = getNext(iterator); // undefined after last item if (tmp !== undefined) { "pattern"  tmp } else { "pattern"  default_value } "elements"  iterator
  • (3e) , "elements" ← iterator(hull, elision)
     getNext(iterator); // skip "elements"  iterator
  • (3f) ..."pattern" ← iterator (alltid siste del!)
     const tmp = ; for (const elem of iterator) { tmp.push(elem); } "pattern"  tmp
  • (3g) ← iterator(ingen elementer igjen)
     // Nothing to do

Helper funksjon:

function getNext(iterator) { const {done,value} = iterator.next(); return (done ? undefined : value);}

10.11.2 bruke algoritmen #

I ECMAScript 6, kan du simulere navngitte parametere hvis den som ringer bruker en objekt bokstavelig og callee bruker destrukturering. Denne simuleringen er forklart i detalj i kapittelet om parameterhåndtering. Følgende kode viser et eksempel: funksjonen move1() har to navngitte parametere, x og y:

function move1({x=0, y=0} = {}) { // (A) return ;}move1({x: 3, y: 8}); // move1({x: 3}); // move1({}); // move1(); // 

det er tre standardverdier i linje A:

  • de to første standardverdiene lar deg utelate x og y.
  • den tredje standardverdien lar deg ringe move1() uten parametere (som i siste linje).

men hvorfor ville du definere parametrene som i forrige kodebit? Hvorfor ikke som følger-som også er helt lovlig ES6-kode?

function move2({x, y} = { x: 0, y: 0 }) { return ;}

For å se hvorfor move1() er riktig, la oss bruke begge funksjonene for to eksempler. Før vi gjør det, la oss se hvordan bestått av parametere kan forklares via matching.

10.11.2.1 Bakgrunn: passerer parametere via matchende #

for funksjonssamtaler, formelle parametere (inne funksjonsdefinisjoner) er matchet mot faktiske parametere(inne funksjonssamtaler). Som et eksempel, ta følgende funksjonsdefinisjon og følgende funksjonskall.

function func(a=0, b=0) { ··· }func(1, 2);

parametrene a og b er satt opp på samme måte som følgende destrukturering.

  
10.11.2.2 Bruke move2() #

La oss undersøke hvordan destrukturering fungerer for move2().

Eksempel 1. move2() fører til denne destruktureringen:

  

det enkle Arrayelementet på venstre side har ikke en kamp på høyre side, og derfor er {x,y} matchet mot standardverdien og ikke mot data fra høyre side (regler 3b, 3d):

{x, y}  { x: 0, y: 0 }

venstre side inneholder eiendomsverdi shorthands, det er en forkortelse for:

{x: x, y: y}  { x: 0, y: 0 }

denne destruktureringen fører til følgende to oppdrag (regler 2c, 1):

x = 0;y = 0;

Eksempel 2. La oss undersøke funksjonskallet move2({z:3}) som fører til følgende destrukturering:

  

Det er Et Matriseelement ved indeks 0 på høyre side. Standardverdien ignoreres derfor, og neste trinn er (regel 3d):

{x, y}  { z: 3 }

Det fører til at både x og y blir satt til undefined, noe som ikke er det vi vil ha.

10.11.2.3 Bruke move1() #

La oss prøve move1().

Eksempel 1: move1()

  

Vi har ikke Et Arrayelement på indeks 0 på høyre side og bruker standardverdien (regel 3d):

{x=0, y=0}  {}

venstre side inneholder egenskapsverdi shorthands, noe som betyr at denne destruktureringen tilsvarer:

{x: x=0, y: y=0}  {}

verken eiendom x eller eiendom y har et samsvar på høyre side. Derfor brukes standardverdiene, og følgende destruksjoner utføres neste (regel 2d):

x  0y  0

det fører til følgende oppgaver (regel 1):

x = 0y = 0

Eksempel 2: move1({z:3})

  

Det første elementet i Matrisemønsteret har en kamp på høyre side, og den kampen brukes til å fortsette destrukturering (regel 3d):

{x=0, y=0}  {z:3}

Som i eksempel 1 er det ingen egenskaper x og y på høyre side, og standardverdiene brukes:

x = 0y = 0
10.11.2.4 Konklusjon #

eksemplene viser at standardverdier er en funksjon av mønsterdeler (objektegenskaper eller Matriseelementer). Hvis en del ikke samsvarer eller matches mot undefined, brukes standardverdien. Det vil si at mønsteret matches mot standardverdien, i stedet.