10. Destruktion

10. Destruktion #

  • 10.1. Oversigt
    • 10.1.1. Objekt ødelæggelse
    • 10.1.2. Array destrukturering
    • 10.1.3. Hvor kan destrukturering bruges?
  • 10.2. Baggrund: konstruktion af data versus udtrækning af data
  • 10.3. Mønstre til destruktion
    • 10.3.1. Vælg hvad du har brug for
  • 10.4. Hvordan får mønstre adgang til indersiden af værdier?
    • 10.4.1. Objektmønstre tvinger værdier til objekter
    • 10.4.2. Array mønstre arbejde med iterables
  • 10.5. Standardværdier
    • 10.5.1. undefined udløser standardværdier
    • 10.5.2. Standardværdier beregnes efter behov
    • 10.5.3. Standardværdier kan henvise til andre variabler i mønsteret
    • 10.5.4. Standardværdier for mønstre
    • 10.5.5. Mere komplekse standardværdier
  • 10.6. Flere objekt destrukturering funktioner
    • 10.6.1. Ejendom værdi shorthands
    • 10.6.2. Beregnede ejendomsnøgler
  • 10.7. Flere array destrukturering funktioner
    • 10.7.1. Elision
    • 10.7.2. Rest operator (...)
  • 10.8. Du kan tildele mere end blot variabler
  • 10.9. Faldgruber af destrukturering
    • 10.9.1. Start ikke en erklæring med en krøllet bøjle
  • 10.10. Eksempler på destruktion
    • 10.10.1. Destrukturering returnerede Arrays
    • 10.10.2. Destrukturering returnerede objekter
    • 10.10.3. Array-destrukturering iterable værdier
    • 10.10.4. Flere returværdier
  • 10.11. Destruktureringsalgoritmen
    • 10.11.1. Algoritmen
    • 10.11.2. Anvendelse af algoritmen

10.1 oversigt #

Destrukturering er en bekvem måde at udtrække flere værdier fra data gemt i (muligvis indlejrede) objekter og Arrays. Det kan bruges på steder, der modtager data (f.eks. i venstre side af en opgave). Sådan udtrækkes værdierne specificeres via mønstre (læs videre for eksempler).

10.1.1 objekt destrukturering #

Destrukturering 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 hjælper med behandling af returværdier:

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

10.1.2 Array destrukturering #

Array destrukturering (virker for alle iterable værdier):

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

Destrukturering hjælper med behandling af returværdier:

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

10.1.3 Hvor kan destrukturering bruges? #

Destrukturering kan bruges på følgende steder (jeg viser Array mønstre for at demonstrere; objekt mønstre fungerer lige så godt):

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

du kan også destruere i en for-of loop:

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

10.2 baggrund: konstruktion af data versus udtrækning af data #

for fuldt ud at forstå, hvad destrukturering er, lad os først undersøge dens bredere kontekst.

JavaScript har operationer til konstruktion af data, en ejendom ad gangen:

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

den samme syntaks kan bruges til at udtrække data. Igen, en ejendom ad gangen:

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

derudover er der syntaks til at konstruere flere egenskaber på samme tid via et objekt bogstaveligt:

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

før ES6 var der ingen tilsvarende mekanisme til udvinding af data. Det er hvad destrukturering er-det giver dig mulighed for at udtrække flere egenskaber fra et objekt via et objektmønster. For eksempel på venstre side af en opgave:

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

du kan også destruere Arrays via mønstre:

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

10.3 mønstre til destrukturering #

følgende to parter er involveret i destrukturering:

  • Destruktureringskilde: de data, der skal destrueres. For eksempel højre side af en destruktureringsopgave.
  • Destruktureringsmål: mønsteret anvendt til destrukturering. For eksempel venstre side af en destruktureringsopgave.

destruktureringsmålet er enten et af tre mønstre:

  • opgave mål. For eksempel: x
    • et tildelingsmål er normalt en variabel. Men i destrukturering opgave, du har flere muligheder, som jeg vil forklare senere.
  • objekt mønster. For eksempel: { first: "pattern", last: "pattern" }
    • dele af et objektmønster er egenskaber, egenskabsværdierne er igen mønstre (rekursivt).
  • Array mønster. For eksempel:
    • dele af et Array mønster er elementer, elementerne er igen mønstre (rekursivt).

det betyder, at du kan rede mønstre, vilkårligt dybt:

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

10.3.1 Vælg hvad du har brug for #

hvis du ødelægger et objekt, nævner du kun de egenskaber, du er interesseret i:

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

hvis du destruerer et Array, kan du vælge kun at udtrække et præfiks:

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

10.4 Hvordan får mønstre adgang til indersiden af værdier? #

i en opgave pattern = someValue, hvordan får pattern adgang til hvad der er indeni someValue?

10.4.1 Objektmønstre tvinger værdier til objekter #

objektmønsteret tvinger destrueringskilder til objekter, før de får adgang til Egenskaber. Det betyder, at det fungerer med primitive værdier:

const {length : len} = 'abc'; // len = 3const {toString: s} = 123; // s = Number.prototype.toString
10.4.1.1 manglende objekt-destrukturering af en værdi #

tvang til objekt udføres ikke via Object(), men via den interne operation ToObject(). De to operationer håndterer undefined og null forskelligt.

Object() konverterer primitive værdier til indpakning objekter og efterlader objekter uberø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 følge heraf kan du bruge det tomme objektmønster {} til at kontrollere, om en værdi kan tvinges til et objekt. Som vi har set, er kun undefined og null ikke:

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

parenteserne omkring udtrykkene er nødvendige, fordi udsagn ikke må begynde med krøllede seler i JavaScript (detaljer forklares senere).

10.4.2 Array mønstre arbejde med iterables #

Array destrukturering bruger en iterator til at komme til elementerne i en kilde. Derfor kan du array-destrukturere enhver værdi, der kan gentages. Lad os se på eksempler på iterable værdier.

strenge er iterable:

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

glem ikke, at iteratoren over strenge returnerer kodepunkter (“Unicode-tegn”, 21 bit), ikke kodeenheder (“JavaScript-tegn”, 16 bit). (For mere information om Unicode, se kapitlet ” Kapitel 24. Unicode og JavaScript ” i “talende JavaScript”.) For eksempel:

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

du kan ikke få adgang til elementerne i et sæt via indekser, men du kan gøre det via en iterator. Derfor arbejder array destructuring for sæt:

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

Set iteratoren returnerer altid elementer i den rækkefølge, de blev indsat i, hvorfor resultatet af den tidligere destrukturering altid er det samme.

10.4.2.1 manglende array-destrukturering af en værdi #

en værdi kan gentages, hvis den har en metode, hvis nøgle er Symbol.iterator, der returnerer et objekt. Array-destrukturering kaster en TypeError hvis værdien, der skal destrueres, ikke kan gentages:

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 adgang til elementer i iterable, hvilket betyder, at du kan bruge det tomme Array mønster for at kontrollere, om en værdi er iterable:

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

10.5 standardværdier #

standardværdier er en valgfri funktion af mønstre. De giver en tilbagegang, hvis der ikke findes noget i kilden. Hvis en del (en objektegenskab eller et Array-element) ikke har nogen match i kilden, matches den mod:

  • dens standardværdi (hvis angivet; det er valgfrit)
  • undefined (ellers)

lad os se på et eksempel. I den følgende destrukturering har elementet ved indeks 0 ingen match på højre side. Derfor fortsætter destrukturering ved at matche x mod 3, hvilket fører til, at x er indstillet til 3.

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

du kan også bruge standardværdier i objektmønstre:

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

10.5.1 undefined udløser standardværdier #

standardværdier bruges også, hvis en del har et match, og det match er undefined:

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

begrundelsen for denne adfærd forklares i det næste kapitel i afsnittet om parameterstandardværdier.

10.5.2 standardværdier beregnes efter behov #

selve standardværdierne beregnes kun, når de er nødvendige. Med andre ord, denne ødelæggelse:

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

svarer til:

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

du kan observere, at hvis du bruger 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

imidlertid, ordre betyder noget: variablerne x og y erklæres fra venstre mod højre og producerer en ReferenceError, hvis de er tilgængelige før deres erklæringer:

const  = ; // ReferenceError

10.5.4 standardværdier for mønstre #

indtil videre har vi kun set standardværdier for variabler, men du kan også knytte dem til mønstre:

const  = ;

hvad betyder det? Husk reglen for standardværdier: hvis en del ikke har noget match i kilden, fortsætter destruktureringen med standardværdien.

elementet ved indeks 0 har ingen match, hvorfor destrukturering fortsætter med:

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

du kan lettere se, hvorfor tingene fungerer på denne måde, hvis du erstatter mønsteret { prop: x } med variablen pattern:

const  = ;

10.5.5 mere komplekse standardværdier #

lad os yderligere undersøge standardværdier for mønstre. I det følgende eksempel tildeler vi en værdi til x via standardværdien { prop: 123 }:

const  = ;

da arrayelementet ved indeks 0 ikke har nogen match på højre side, fortsætter destruktureringen som følger, og x er indstillet til 123.

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

x tildeles dog ikke en værdi på denne måde, hvis højre side har et element ved indeks 0, fordi standardværdien ikke udløses.

const  = ;

i dette tilfælde fortsætter ødelæggelsen med:

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

Således, hvis du vil have x til at være 123, hvis enten objektet eller ejendommen mangler, skal du angive en standardværdi for x selv:

const  = ;

her fortsætter destruktureringen som følger, uafhængigt af om højre side er eller .

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

10.6 flere objekt destrukturering funktioner #

10.6.1 egenskabsværdi shorthands #

egenskabsværdi shorthands er en funktion af objekt literals: Hvis egenskabsværdien er en variabel, der har samme navn som egenskabsnøglen, kan du udelade nøglen. Dette fungerer også til destruktion:

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 egenskabsværdi shorthands med standardværdier:

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

10.6.2 beregnede egenskabsnøgler #

beregnede egenskabsnøgler er en anden objekt bogstavelig funktion, der også virker til destruktion. Du kan angive nøglen til en ejendom via et udtryk, hvis du sætter det i firkantede parenteser:

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

beregnede egenskabsnøgler giver dig mulighed for at destruere egenskaber, hvis nøgler 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 destrukturering funktioner #

10.7.1 Elision #

Elision lader dig bruge syntaksen af Array “huller” til at springe elementer under destruering:

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

10.7.2 Rest operator (...) #

resten operatør kan du udtrække de resterende elementer i en iterable i et Array. Hvis denne operatør bruges inde i et Array mønster, skal det komme sidst:

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

hvis operatøren ikke kan finde nogen elementer, matcher den sin operand mod det tomme Array. Det vil sige, det producerer aldrig undefinedeller null. For eksempel:

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

resten operatørens operand behøver ikke at være en variabel, du kan også bruge mønstre:

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

resten operatør udløser følgende destrukturering:

 = 

10.8 Du kan tildele mere end blot variabler #

hvis du tildeler via destrukturering, kan hvert tildelingsmål være alt, hvad der er tilladt på venstre side af en normal tildeling.

for eksempel en henvisning til en ejendom (obj.prop):

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

eller en henvisning til et Array element (arr):

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

du kan også tildele objektegenskaber og Array-elementer via rest-operatøren (...):

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

hvis du erklærer variabler eller definerer parametre via destrukturering, skal du bruge enkle identifikatorer, du kan ikke henvise til objektegenskaber og arrayelementer.

10.9 faldgruber af destrukturering #

der er to ting at være opmærksom på, når du bruger destrukturering:

  • du kan ikke starte en erklæring med en krøllet bøjle.
  • under destrukturering kan du enten erklære variabler eller tildele dem, men ikke begge dele.

de næste to afsnit indeholder detaljerne.

10.9.1 start ikke en erklæring med en krøllet bøjle #

da kodeblokke begynder med en krøllet bøjle, må udsagn ikke begynde med en. Dette er uheldigt, når du bruger objektdestrukturering i en opgave:

{ a, b } = someObject; // SyntaxError

arbejdet er at sætte det komplette udtryk i parentes:

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

følgende syntaks virker ikke:

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

med let, var og const forårsager krøllede seler aldrig problemer:

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

10.10 Eksempler på destrukturering #

lad os starte med et par mindre eksempler.

den for-of loop understøtter destrukturering:

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

du kan bruge destrukturering til at bytte værdier. Det er noget, som motorer kunne optimere, så der ikke oprettes noget Array.

 = ;

du kan bruge destrukturering til at opdele et Array:

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

10.10.1 Destrukturering returnerede Arrays #

nogle indbyggede JavaScript-operationer returnerer Arrays. Destrukturering hjælper med at behandle dem:

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

hvis du kun er interesseret i grupperne (og ikke i det komplette match, all), kan du bruge elision til at springe array-elementet over ved indeks 0:

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

exec() returnerer null, hvis det regulære udtryk ikke stemmer overens. Desværre kan du ikke håndtere null via standardværdier, hvorfor du skal bruge or-operatøren (||) i dette tilfælde:

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

Array.prototype.split() returnerer et Array. Derfor er destrukturering nyttig, hvis du er interesseret i elementerne, ikke arrayet:

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

10.10.2 Destrukturering returnerede objekter #

Destrukturering er også nyttig til at udtrække data fra objekter, der returneres af funktioner eller metoder. For eksempel returnerer iteratormetoden next() et objekt med to egenskaber, done og value. Følgende kode logger alle elementer i Array arr via iteratoren iter. Destrukturering anvendes 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 værdier #

Array-destrukturering arbejder med enhver iterable værdi. Det er lejlighedsvis nyttigt:

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

10.10.4 flere returværdier #

for at se nytten af flere returværdier, lad os implementere en funktion findElement(a, p), der søger efter det første element i arrayet a, som funktionen preturnerer true. Spørgsmålet er: hvad skal findElement() vende tilbage? Nogle gange er man interesseret i selve elementet, nogle gange i sit indeks, nogle gange i begge. Følgende implementering returnerer begge dele.

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 };}

funktionen gentager over alle elementer af array via Array-metoden entries(), som returnerer en iterabel over par (linje A). Parrets dele er tilgængelige via destruktion.

lad os bruge findElement():

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

flere ECMAScript 6 funktioner tillod os at skrive mere kortfattet kode: tilbagekaldelsen er en pilfunktion; returværdien ødelægges via et objektmønster med ejendomsværdi shorthands.

på grund af index og element henviser også til egenskabsnøgler, den rækkefølge, vi nævner dem i, betyder ikke noget. Vi kan bytte dem, og intet ændrer sig:

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

vi har med succes håndteret sagen om at have brug for både indeks og element. Hvad hvis vi kun er interesseret i en af dem? Det viser sig, at takket være ECMAScript 6 kan vores implementering også tage sig af det. Og den syntaktiske overhead sammenlignet med funktioner med enkelt returværdier 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 udvinder vi kun værdien af den ene ejendom, vi har brug for.

10.11 destruktureringsalgoritmen #

dette afsnit ser på destrukturering fra en anden vinkel: som en rekursiv mønstertilpasningsalgoritme.

i slutningen bruger jeg algoritmen til at forklare forskellen mellem de følgende to funktionserklæringer.

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

10.11.1 algoritmen #

en destruktureringsopgave ser sådan ud:

"pattern" = "value"

vi vil bruge pattern til at udtrække data fra value. Jeg vil nu beskrive en algoritme til at gøre det, som er kendt i funktionel programmering som mønstertilpasning (kort: matching). Algoritmen specificerer operatøren (“match mod”) til destruktureringstildeling, der matcher en pattern mod en value og tildeler variabler, mens du gør det:

"pattern"  "value"

algoritmen er specificeret via rekursive regler, der adskiller begge operander af operatoren. Den deklarative notation kan tage noget at vænne sig til, men det gør specifikationen af algoritmen mere kortfattet. Hver regel har to dele:

  • hovedet (første linje) beskriver den tilstand, der udløser reglen.
  • kroppen (resterende linjer) beskriver, hvad der sker, hvis reglen udløses.

lad os se på et eksempel:

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

i regel (2C) betyder hovedet, at denne regel udføres, hvis der er et objektmønster med mindst en egenskab og nul eller flere resterende egenskaber. Dette mønster matches med en værdi obj. Effekten af denne regel er, at udførelsen fortsætter med, at egenskabsværdimønsteret matches med obj.key, og de resterende egenskaber matches med obj.

i regel (2e) betyder hovedet, at denne regel udføres, hvis det tomme objektmønster {}matches med en værdi obj. Så er der intet at gøre.

når algoritmen påberåbes, kontrolleres reglerne top til bund, og kun den første regel, der gælder, udføres.

jeg viser kun algoritmen til destrukturering opgave. Destrukturering variable erklæringer og destrukturering parameter definitioner arbejde på samme måde.

jeg dækker ikke avancerede funktioner (beregnede ejendomsnøgler; ejendomsværdi shorthands; objektegenskaber og array-elementer som tildelingsmål), enten. Kun det grundlæggende.

10.11.1.1 mønstre #

et mønster er enten:

  • en variabel: x
  • et objekt mønster: {"properties"}
  • et Array mønster:

hvert af de følgende afsnit beskriver et af disse tre tilfælde.

de følgende tre afsnit angiver, hvordan disse tre sager skal håndteres. Hvert afsnit indeholder en eller flere nummererede regler.

10.11.1.2 variabel #
  • (1) x ← value (herunder 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 ejendomme tilbage)
     // Nothing to do
10.11.1.4 Array mønster #

Array mønster og iterable. Algoritmen til 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

hjælper funktion:

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

Array elementer og iterator. Algoritmen fortsætter med elementerne i mønsteret (venstre side af pilen) og iteratoren, der blev opnået fra den iterable (højre side af 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 (hul, elision)
     getNext(iterator); // skip "elements"  iterator
  • (3f) ..."pattern" ← iterator( altid sidste del!)
     const tmp = ; for (const elem of iterator) { tmp.push(elem); } "pattern"  tmp
  • (3g) ← iterator (ingen elementer tilbage)
     // Nothing to do

hjælper funktion:

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

10.11.2 anvendelse af algoritmen #

i ECMAScript 6 kan du simulere navngivne parametre, hvis den, der ringer op, bruger et objekt bogstaveligt, og callee bruger destrukturering. Denne simulering forklares detaljeret i kapitlet om parameterhåndtering. Følgende kode viser et eksempel: funktion move1() har to navngivne parametre, x og y:

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

der er tre standardværdier i linje A:

  • de to første standardværdier giver dig mulighed for at udelade x og y.
  • den tredje standardværdi giver dig mulighed for at ringe move1() uden parametre (som i den sidste linje).

men hvorfor ville du definere parametrene som i det foregående kodestykke? Hvorfor ikke som følger-hvilket også er helt lovligt ES6 kode?

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

for at se hvorfor move1() er korrekt, lad os bruge begge funktioner til to eksempler. Før vi gør det, lad os se, hvordan passering af parametre kan forklares via matching.

10.11.2.1 baggrund: passerer parametre via matchende #

for funktionsopkald matches formelle parametre (indvendige funktionsdefinitioner) med faktiske parametre (indvendige funktionsopkald). Tag som eksempel følgende funktionsdefinition og følgende funktionsopkald.

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

parametrene a og b er sat op på samme måde som følgende destrukturering.

  
10.11.2.2 brug af move2() #

lad os undersøge, hvordan destrukturering virker for move2().

eksempel 1. move2() fører til denne ødelæggelse:

  

det enkelte arrayelement på venstre side har ikke en match på højre side, hvorfor {x,y} matches mod standardværdien og ikke mod data fra højre side (regler 3b, 3d):

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

den venstre side indeholder ejendomsværdi shorthands, det er en forkortelse for:

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

denne destrukturering fører til følgende to opgaver (regler 2C, 1):

x = 0;y = 0;

eksempel 2. Lad os undersøge funktionskaldet move2({z:3}), som fører til følgende ødelæggelse:

  

der er et Array element ved indeks 0 på højre side. Derfor ignoreres standardværdien, og det næste trin er (regel 3d):

{x, y}  { z: 3 }

det fører til, at både x og y er indstillet til undefined, hvilket ikke er det, vi ønsker.

10.11.2.3 brug af move1() #

lad os prøve move1().

eksempel 1: move1()

  

vi har ikke et Array-element ved indeks 0 på højre side og bruger standardværdien (regel 3d):

{x=0, y=0}  {}

den venstre side indeholder ejendomsværdi shorthands, hvilket betyder, at denne destrukturering svarer til:

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

hverken ejendom x eller ejendom y har et match på højre side. Derfor anvendes standardværdierne, og følgende ødelæggelser udføres næste (regel 2D):

x  0y  0

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

x = 0y = 0

eksempel 2: move1({z:3})

  

det første element i Arraymønsteret har en kamp på højre side, og den kamp bruges til at fortsætte destruktureringen (regel 3d):

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

som I eksempel 1 er der ingen egenskaber x og y på højre side, og standardværdierne bruges:

x = 0y = 0
10.11.2.4 konklusion #

eksemplerne viser, at standardværdier er en funktion af mønsterdele (objektegenskaber eller arrayelementer). Hvis en del ikke har noget match eller matches med undefined, bruges standardværdien. Det vil sige, at mønsteret matches med standardværdien i stedet.