10. Vernietiging

10. Vernietiging #

  • 10.1. Overzicht
    • 10.1.1. Vernietiging van objecten
    • 10.1.2. Array destructuring
    • 10.1.3. Waar kan vernietiging worden gebruikt?
  • 10.2. Achtergrond: construeren van gegevens versus extraheren van gegevens
  • 10.3. Patronen voor vernietiging
    • 10.3.1. Kies wat je nodig hebt
  • 10.4. Hoe krijgen patronen toegang tot de ingewanden van waarden?
    • 10.4.1. Objectpatronen dwingen waarden tot objecten
    • 10.4.2. Array patronen werken met iterables
  • 10.5. Standaardwaarden
    • 10.5.1. undefined triggers standaardwaarden
    • 10.5.2. Standaardwaarden worden berekend op aanvraag
    • 10.5.3. Standaardwaarden kunnen verwijzen naar andere variabelen in het patroon
    • 10.5.4. Standaardwaarden voor patronen
    • 10.5.5. Complexere standaardwaarden
  • 10.6. Meer objectdestructieve functies
    • 10.6.1. Waarde van het onroerend goed steno
    • 10.6.2. Berekende eigenschappensleutels
  • 10.7. Meer array-destructiefuncties
    • 10.7.1. Elisie
    • 10.7.2. Exploitant van rusttijden (...)
  • 10.8. U kunt meer dan alleen variabelen
  • 10.9 toewijzen. Valkuilen van de vernietiging
    • 10.9.1. Begin geen statement met een krullende brace
  • 10.10. Voorbeelden van destructie
    • 10.10.1. Destructuring gaf Arrays
    • 10.10.2. Het vernietigen van geretourneerde objecten
    • 10.10.3. Array-destructuring iterbare waarden
    • 10.10.4. Meerdere retourwaarden
  • 10.11. Het vernietigingsalgoritme
    • 10.11.1. Het algoritme
    • 10.11.2. Het algoritme toepassen

10.1 overview #

vernietiging is een handige manier om meerdere waarden te extraheren uit gegevens die zijn opgeslagen in (mogelijk geneste) objecten en Arrays. Het kan worden gebruikt op locaties die gegevens ontvangen (zoals de linkerkant van een opdracht). Hoe de waarden te extraheren wordt gespecificeerd via patronen (Lees verder voor voorbeelden).

10.1.1 vernietiging van objecten #

vernietiging van objecten:

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'

Destructuring helpt met het verwerken van de retour waarden:

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

10.1.2 Array destructuring #

Array destructuring (werkt voor alle iterable waarden):

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

Destructuring helpt met het verwerken van de retour waarden:

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

10.1.3 Waar kan destructuring worden gebruikt? #

vernietiging kan op de volgende locaties worden gebruikt (Ik toon Array patronen om aan te tonen; object patronen werken net zo goed):

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

u kunt ook vernietigen in een lus for-of :

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

10.2 Achtergrond: construeren van data versus extraheren van data #

om volledig te begrijpen wat destructeren is, laten we eerst de bredere context ervan onderzoeken.

JavaScript heeft bewerkingen voor het construeren van data, één eigenschap tegelijk:

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

dezelfde syntaxis kan worden gebruikt om gegevens te extraheren. Nogmaals, één eigendom per keer:

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

Daarnaast is er syntaxis om meerdere eigenschappen tegelijkertijd te construeren, via een object letterlijk:

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

vóór ES6 was er geen overeenkomstig mechanisme voor het extraheren van gegevens. Dat is wat destructing is-het laat je meerdere eigenschappen van een object extraheren via een objectpatroon. Bijvoorbeeld, aan de linkerkant van een opdracht:

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

u kunt ook arrays vernietigen via patronen:

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

10.3 patronen voor vernietiging #

de volgende twee partijen zijn betrokken bij vernietiging:

  • bron: de gegevens die vernietigd moeten worden. Bijvoorbeeld, de rechterkant van een destructieopdracht.
  • Destructiedoel: het patroon dat wordt gebruikt voor destructiedoeleinden. Bijvoorbeeld, de linkerkant van een destructieopdracht.

het vernietigingsdoel is een van de drie patronen:

  • opdracht doel. Bijvoorbeeld:: x
    • een toegewezen doel is meestal een variabele. Maar bij de vernietigingstaak heb je meer opties, zoals ik later zal uitleggen.
  • Objectpatroon. Bijvoorbeeld:: { first: "pattern", last: "pattern" }
    • de delen van een objectpatroon zijn eigenschappen, de eigenschapswaarden zijn opnieuw patronen (recursief).
  • Array patroon. Bijvoorbeeld::
    • de delen van een Array patroon zijn elementen, de elementen zijn weer patronen (recursief).

dat betekent dat je patronen kunt nestelen, willekeurig diep:

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

10.3.1 Kies wat je nodig hebt #

als je een object vernietigt, vermeld je alleen de eigenschappen waarin je geïnteresseerd bent:

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

als u een Array vernietigt, kunt u ervoor kiezen om alleen een voorvoegsel te extraheren:

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

10.4 hoe krijgen patronen toegang tot de ingewanden van waarden? #

In een opdracht pattern = someValue, hoe krijgt pattern toegang tot wat er in someValuezit?

10.4.1 Objectpatronen dwingen waarden naar objecten #

het objectpatroon dwingt destructieve bronnen naar objecten voordat ze eigenschappen benaderen. Dat betekent dat het werkt met primitieve waarden:

const {length : len} = 'abc'; // len = 3const {toString: s} = 123; // s = Number.prototype.toString
10.4.1.1 een waarde #

niet vernietigen van objecten de dwang tot object wordt niet uitgevoerd via Object(), maar via de interne operatie ToObject(). De twee operaties behandelen undefined en null verschillend.

Object() converteert primitieve waarden naar wrapper-objecten en laat objecten onaangeroerd:

> 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

als gevolg hiervan kunt u het lege objectpatroon {} gebruiken om te controleren of een waarde dwingend is voor een object. Zoals we hebben gezien, zijn alleen undefined en null :

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

de haakjes rond de uitdrukkingen zijn nodig omdat statements niet moeten beginnen met accolades in JavaScript (details worden later uitgelegd).

10.4.2 Array patronen werken met iterables #

Array destructuring gebruikt een iterator om bij de elementen van een bron te komen. Daarom kunt u Array-destructure elke waarde die is iterable. Laten we eens kijken naar voorbeelden van herhalbare waarden.

tekenreeksen kunnen herhaald worden:

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

vergeet niet dat de iterator over strings Codepunten retourneert (“Unicode characters”, 21 bits), geen codeeenheden (“JavaScript characters”, 16 bits). (Voor meer informatie over Unicode, raadpleeg het hoofdstuk ” Hoofdstuk 24. Unicode en JavaScript ” in “sprekende JavaScript”.) Bijvoorbeeld:

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

je kunt de elementen van een Set niet benaderen via indices, maar wel via een iterator. Daarom werkt de vernietiging van Array voor Sets:

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

de Set iterator geeft altijd elementen terug in de volgorde waarin ze zijn ingevoegd, daarom is het resultaat van de vorige vernietiging altijd hetzelfde.

10.4.2.1 Array-vernietiging van een waarde #

een waarde kan herhaald worden als het een methode heeft waarvan de sleutel Symbol.iterator is die een object retourneert. Array-destructuring gooit een TypeError als de te vernietigen waarde niet kan worden herhaald:

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

de TypeError wordt gegooid nog voordat u toegang krijgt tot elementen van de iterable, wat betekent dat u het lege Array patroon kunt gebruiken om te controleren of een waarde iterable is:

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

10.5 standaardwaarden #

standaardwaarden zijn een optionele functie van patronen. Ze bieden een terugval als er niets wordt gevonden in de bron. Als een deel (een object-eigenschap of een Array-element) geen overeenkomst heeft in de bron, wordt het vergeleken met:

  • de standaardwaarde (indien gespecificeerd); het is optioneel)
  • undefined (anders)

laten we naar een voorbeeld kijken. In de volgende vernietiging heeft het element op index 0 geen overeenkomst aan de rechterkant. Daarom wordt de vernietiging voortgezet door x te matchen met 3, wat leidt tot x wordt ingesteld op 3.

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

u kunt ook standaardwaarden gebruiken in objectpatronen:

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

10.5.1 undefined triggers standaardwaarden #

standaardwaarden worden ook gebruikt als een onderdeel een overeenkomst heeft en die overeenkomst undefinedis:

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

de reden voor dit gedrag wordt uitgelegd in het volgende hoofdstuk, in de sectie over parameter standaardwaarden.

10.5.2 standaardwaarden worden berekend op aanvraag #

de standaardwaarden zelf worden alleen berekend wanneer ze nodig zijn. Met andere woorden, deze vernietiging:

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

is gelijk aan:

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

je kunt zien dat als je gebruikt 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

echter, orde is van belang: de variabelen x en y worden van links naar rechts gedeclareerd en leveren een ReferenceError op als ze vóór hun declaraties worden gebruikt:

const  = ; // ReferenceError

10.5.4 standaardwaarden voor patronen #

tot nu toe hebben we alleen standaardwaarden voor variabelen gezien, maar u kunt ze ook associëren met patronen:

const  = ;

wat betekent dit? De regel voor standaardwaarden oproepen: als een onderdeel geen overeenkomst heeft in de bron, gaat de vernietiging door met de standaardwaarde.

het element op index 0 heeft geen overeenkomst, daarom gaat de vernietiging verder met:

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

u kunt gemakkelijker zien waarom dingen op deze manier werken als u het patroon { prop: x } vervangt door de variabele pattern:

const  = ;

10.5.5 complexere standaardwaarden #

laten we de standaardwaarden voor patronen verder onderzoeken. In het volgende voorbeeld kennen we een waarde toe aan x via de standaardwaarde { prop: 123 }:

const  = ;

omdat het Array-element bij index 0 aan de rechterkant geen overeenkomst heeft, gaat de vernietiging als volgt door en wordt x ingesteld op 123.

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

x wordt echter niet op deze manier een waarde toegewezen als de rechterkant een element op index 0 heeft, omdat dan de standaardwaarde niet wordt geactiveerd.

const  = ;

in dit geval gaat de vernietiging door met:

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

dus als u wilt dat x 123 is als het object of de eigenschap ontbreekt, moet u een standaardwaarde opgeven voor x zelf:

const  = ;

hier gaat de vernietiging als volgt verder, ongeacht of de rechterkant of is.

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

10.6 meer objectdestructie-eigenschappen #

10.6.1 Eigenschappenwaarde stenografen #

Eigenschappenwaarde stenografen zijn een eigenschap van objectletters: Als de eigenschap waarde een variabele is die dezelfde naam heeft als de eigenschap sleutel dan kunt u de sleutel weglaten. Dit werkt ook voor vernietiging.:

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

u kunt ook eigenschapswaarde stenografisch combineren met standaardwaarden:

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

10.6.2 Computed property keys #

Computed property keys zijn een andere object letterlijke functie die ook werkt voor vernietiging. U kunt de sleutel van een eigenschap opgeven via een expressie, als u deze tussen vierkante haakjes plaatst:

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

Berekend eigendom toetsen kunt u destructure eigenschappen waarvan de sleutels zijn symbolen:

// 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 Meer Array destructuring features #

10.7.1 Elision #

Elision kun je de syntaxis van de Array “gaten” overslaan elementen tijdens destructuring:

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

10.7.2 Rest van de operator (...) #

De rest van de operator, kunt u uitpakken van de overige elementen van een iterable in een Matrix. Als deze operator binnen een Array-patroon wordt gebruikt, moet deze als laatste komen:

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

als de operator geen elementen kan vinden, zal hij zijn operand matchen met de lege Array. Dat wil zeggen, het produceert nooit undefined of null. Bijvoorbeeld::

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

de operand van de rest operator hoeft geen variabele te zijn, je kunt ook patronen gebruiken:

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

de rest operator activeert de volgende vernietiging:

 = 

10.8 u kunt aan meer dan alleen variabelen #

toewijzen als u via destructuring toewijst, kan elk toegewezen doel alles zijn wat is toegestaan aan de linkerkant van een normale toewijzing.

bijvoorbeeld een verwijzing naar een eigenschap (obj.prop):

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

of een verwijzing naar een Array-element (arr):

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

u kunt ook objecteigenschappen en Array-elementen toewijzen via de rest-operator (...):

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

als je variabelen declareert of parameters definieert via destructuring dan moet je eenvoudige identifiers gebruiken, je kunt niet verwijzen naar objecteigenschappen en Array-elementen.

10.9 valkuilen van de destructie #

er zijn twee dingen om op te letten bij het gebruik van destructie:

  • je kunt een verklaring niet beginnen met een krullende beugel.
  • tijdens het vernietigen kunt u variabelen declareren of toewijzen, maar niet beide.

de volgende twee secties bevatten de details.

10.9.1 Begin een statement niet met een accolade #

omdat codeblokken beginnen met een accolade, moeten statements niet met een accolade beginnen. Dit is vervelend bij het gebruik van object destructuring in een opdracht:

{ a, b } = someObject; // SyntaxError

De work-around is om de volledige expressie tussen haakjes:

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

De volgende syntaxis werkt niet:

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

Met let, var en const, accolades nooit de oorzaak zijn van problemen:

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

10.10 voorbeelden van vernietiging #

laten we beginnen met een paar kleinere voorbeelden.

de for-of lus ondersteunt de vernietiging:

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

u kunt destructing gebruiken om waarden te wisselen. Dat is iets dat motoren kunnen optimaliseren, zodat er geen Array zou worden gemaakt.

 = ;

u kunt destructing gebruiken om een Array te splitsen:

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

10.10.1 Destructuring retourneerde Arrays #

sommige ingebouwde JavaScript-bewerkingen retourneren Arrays. Vernietigen helpt bij het verwerken ervan:

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

Als u alleen geïnteresseerd bent in de groepen (en niet in de volledige overeenkomst, all), kunt u elision gebruiken om het array-element bij index over te slaan 0:

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

exec() geeft null terug als de reguliere expressie niet overeenkomt. Helaas kunt u null niet verwerken via standaardwaarden, daarom moet u in dit geval de OR-operator (||) gebruiken:

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

Array.prototype.split() geeft een Array terug. Daarom is vernietiging nuttig als je geïnteresseerd bent in de elementen, niet in de Array:

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

10.10.2 vernietiging van geretourneerde objecten #

vernietiging is ook nuttig voor het extraheren van gegevens van objecten die worden geretourneerd door functies of methoden. Bijvoorbeeld, de iterator methode next() geeft een object met twee eigenschappen, done en value. De volgende code logt alle elementen van Array arr via de iterator iter. Vernietiging wordt gebruikt in lijn A.

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

10.10.3 Array-destructuring iterbare waarden #

Array-destructuring werkt met elke iterbare waarde. Dat is soms nuttig:

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

10.10.4 meerdere retourwaarden #

om het nut van meerdere retourwaarden te zien, implementeren we een functie findElement(a, p) die zoekt naar het eerste element in de Array a waarvoor de functie p trueretourneert. De vraag is: wat moet findElement() teruggeven? Soms is men geïnteresseerd in het element zelf, soms in de index, soms in beide. De volgende implementatie geeft beide terug.

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

de functie itereert over alle elementen van array, via de MatriXmethode entries(), die een iterabel retourneert over paren (regel A). De delen van de paren zijn toegankelijk via vernietiging.

laten we gebruiken findElement():

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

verschillende ECMAScript 6-functies lieten ons toe om meer beknopte code te schrijven: de callback is een pijlfunctie; de retourwaarde wordt vernietigd via een objectpatroon met eigenschapswaarde stenografen.

vanwege index en element die ook verwijzen naar eigenschappensleutels, doet de volgorde waarin we ze noemen er niet toe. We kunnen ze ruilen en er verandert niets.:

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

we hebben het geval van zowel index als element met succes afgehandeld. Wat als we maar in één van hen geïnteresseerd zijn? Het blijkt dat, dankzij ECMAScript 6, onze implementatie daar ook voor kan zorgen. En de syntactische overhead in vergelijking met functies met enkelvoudige retourwaarden Is minimaal.

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

elke keer halen we alleen de waarde van de enige eigenschap die we nodig hebben.

10.11 het vernietigingsalgoritme #

in deze sectie wordt de vernietiging vanuit een andere hoek bekeken: als een recursief patroonvergelijkingsalgoritme.

aan het einde zal ik het algoritme gebruiken om het verschil tussen de volgende twee functie declaraties uit te leggen.

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

10.11.1 het algoritme #

een destructieopdracht ziet er als volgt uit:

"pattern" = "value"

we willen pattern gebruiken om gegevens uit valuete extraheren. Ik zal nu een algoritme beschrijven om dit te doen, dat in functioneel programmeren bekend staat als pattern matching (kort: matching). Het algoritme specificeert de operator (“match against”) voor destructietoewijzing die overeenkomt met een pattern tegen een value en wijst daarbij variabelen toe:

"pattern"  "value"

het algoritme wordt gespecificeerd via recursieve regels die beide operanden van de operator uit elkaar halen. De declaratieve notatie kan enige wennen aan, maar het maakt de specificatie van het algoritme beknopter. Elke regel heeft twee delen:

  • de head (eerste regel) beschrijft de voorwaarde die de regel activeert.
  • de inhoud (resterende regels) beschrijft wat er gebeurt als de regel wordt geactiveerd.

laten we een voorbeeld bekijken:

  • (2c) {key: "pattern", "properties"} ← obj
     "pattern"  obj.key {"properties"}  obj
  • (2e) {} ← obj (geen eigenschappen links)
     // Nothing to do

In regel (2c), het hoofd betekent dat deze regel wordt uitgevoerd als er een object patroon met ten minste één eigenschap en nul of meer woningen. Dat patroon komt overeen met een waarde obj. Het effect van deze regel is dat de uitvoering doorgaat met het eigenschappenwaardepatroon dat wordt vergeleken met obj.key en de overige eigenschappen die worden vergeleken met obj.

in regel (2e) betekent de head dat deze regel wordt uitgevoerd als het lege objectpatroon {} overeenkomt met een waarde obj. Dan is er niets aan te doen.

wanneer het algoritme wordt aangeroepen, worden de regels van boven naar beneden gecontroleerd en wordt alleen de eerste regel uitgevoerd die van toepassing is.

ik Toon alleen het algoritme voor destructietoewijzing. Destructieve variabele declaraties en destructieve parameterdefinities werken op dezelfde manier.

ik heb geen betrekking op Geavanceerde functies (computed property keys; property value shorthands; objecteigenschappen en array-elementen als toegewezen doelen), ofwel. Alleen de basis.

10.11.1.1 patronen #

een patroon is ofwel:

  • een variabele: x
  • een objectpatroon: {"properties"}
  • een Array-patroon:

elk van de volgende paragrafen beschrijft een van deze drie gevallen.

in de volgende drie paragrafen wordt aangegeven hoe deze drie gevallen moeten worden behandeld. Elke sectie bevat een of meer genummerde regels.

10.11.1.2 Variabele #
  • (1) x ← value (inclusief undefined en null)
     x = value
10.11.1.3 Object patroon #
  • (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 (geen eigenschappen links)
     // Nothing to do

10.11.1.4 Array patroon #

Array patroon en iterable. Het algoritme voor het Array destructuring begint met een Matrix patroon en een iterable:

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

Helper functie:

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

Array-elementen en iterator. Het algoritme gaat verder met de elementen van het patroon (linkerkant van de pijl) en de iterator die werd verkregen uit de iterable (rechterkant van de pijl).

  • (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 (gat, elision)
     getNext(iterator); // skip "elements"  iterator
  • (3f) ..."pattern" ← iterator (altijd laatste deel!)
     const tmp = ; for (const elem of iterator) { tmp.push(elem); } "pattern"  tmp
  • (3g) ← iterator (geen elementen links)
     // Nothing to do

Helper functie:

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

10.11.2 het Toepassen van het algoritme #

In ECMAScript 6, u kunt simuleren benoemde parameters als de beller gebruik maakt van een object literal en de opgeroepene gebruikt destructuring. Deze simulatie wordt in detail uitgelegd in het hoofdstuk over parameterverwerking. De volgende code toont een voorbeeld: functie move1() heeft twee benoemde parameters, x en y:

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

er zijn drie standaardwaarden in regel A:

  • met de eerste twee standaardwaarden kunt u x en yweglaten.
  • met de derde standaardwaarde kunt u move1() aanroepen zonder parameters (zoals in de laatste regel).

maar waarom zou u de parameters definiëren zoals in het vorige codefragment? Waarom niet als volgt-dat is ook volledig legaal ES6 code?

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

om te zien waarom move1() correct is, gebruiken we beide functies voor twee voorbeelden. Voordat we dat doen, laten we eens kijken hoe het passeren van parameters kan worden verklaard via matching.

10.11.2.1 Achtergrond: parameters doorgeven via matching #

voor functieaanroepen worden formele parameters (binnen functiedefinities) vergeleken met werkelijke parameters (binnen functieaanroepen). Neem als voorbeeld de volgende functiedefinitie en de volgende functieaanroep.

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

de parameters a en b zijn op dezelfde wijze ingesteld als de volgende destructiemethoden.

  
10.11.2.2 gebruik move2() #

laten we eens kijken hoe destructing werkt voor move2().

Voorbeeld 1. move2() leidt tot deze vernietiging:

  

het enkele Array-element aan de linkerkant heeft geen overeenkomst aan de rechterkant, daarom wordt {x,y} vergeleken met de standaardwaarde en niet met gegevens aan de rechterkant (regels 3b, 3d):

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

de linkerkant bevat eigenschap waarde Afkorting, het is een afkorting voor:

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

deze vernietiging leidt tot de volgende twee opdrachten (regels 2c, 1):

x = 0;y = 0;

Voorbeeld 2. Laten we eens kijken naar de functie aanroep move2({z:3}) die leidt tot de volgende vernietiging:

  

er is een Array element op index 0 aan de rechterkant. Daarom wordt de standaardwaarde genegeerd en de volgende stap is (regel 3d):

{x, y}  { z: 3 }

dat leidt ertoe dat zowel x als y worden ingesteld op undefined, wat niet is wat we willen.

10.11.2.3 gebruik move1() #

laten we move1()proberen.

Voorbeeld 1: move1()

  

we hebben geen Array element op index 0 aan de rechterkant en gebruiken de standaard waarde (regel 3d):

{x=0, y=0}  {}

de linkerkant bevat eigenschapswaarde Steno ‘ s, wat betekent dat deze vernietiging gelijk is aan:

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

eigenschap x noch eigenschap y hebben een overeenkomst aan de rechterkant. Daarom worden de standaardwaarden gebruikt en de volgende destructurings worden uitgevoerd volgende (regel 2d):

x  0y  0

Dat leidt tot de volgende opdrachten (regel 1):

x = 0y = 0

Voorbeeld 2: move1({z:3})

  

Het eerste element van de Array patroon heeft een wedstrijd op de rechterkant en die wedstrijd is gebruikt om te gaan destructuring (regel 3d):

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

zoals in Voorbeeld 1, zijn er geen eigenschappen x en y aan de rechterkant en worden de standaardwaarden gebruikt:

x = 0y = 0
10.11.2.4 conclusie #

de voorbeelden tonen aan dat standaardwaarden een kenmerk zijn van patroondelen (objecteigenschappen of Array-elementen). Als een deel geen overeenkomst heeft of overeenkomt met undefined, wordt de standaardwaarde gebruikt. Dat wil zeggen, het patroon wordt vergeleken met de standaardwaarde, in plaats daarvan.