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.5.1.
- 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:
Destructuring helpt met het verwerken van de retour waarden:
10.1.2 Array destructuring #
Array destructuring (werkt voor alle iterable waarden):
Destructuring helpt met het verwerken van de retour waarden:
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):
u kunt ook vernietigen in een lus for-of
:
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:
dezelfde syntaxis kan worden gebruikt om gegevens te extraheren. Nogmaals, één eigendom per keer:
Daarnaast is er syntaxis om meerdere eigenschappen tegelijkertijd te construeren, via een object letterlijk:
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:
u kunt ook arrays vernietigen via patronen:
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:
10.3.1 Kies wat je nodig hebt #
als je een object vernietigt, vermeld je alleen de eigenschappen waarin je geïnteresseerd bent:
als u een Array vernietigt, kunt u ervoor kiezen om alleen een voorvoegsel te extraheren:
10.4 hoe krijgen patronen toegang tot de ingewanden van waarden? #
In een opdracht pattern = someValue
, hoe krijgt pattern
toegang tot wat er in someValue
zit?
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:
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:
It also converts undefined
and null
to empty objects:
In contrast, ToObject()
throws a TypeError
if it encounters undefined
or null
. Therefore, the following destructurings fail, even before destructuring accesses any properties:
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
:
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:
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:
je kunt de elementen van een Set niet benaderen via indices, maar wel via een iterator. Daarom werkt de vernietiging van Array voor Sets:
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:
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:
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.
u kunt ook standaardwaarden gebruiken in objectpatronen:
10.5.1 undefined
triggers standaardwaarden #
standaardwaarden worden ook gebruikt als een onderdeel een overeenkomst heeft en die overeenkomst undefined
is:
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:
is gelijk aan:
je kunt zien dat als je gebruikt console.log()
:
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:
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:
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:
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:
u kunt gemakkelijker zien waarom dingen op deze manier werken als u het patroon { prop: x }
vervangt door de variabele pattern
:
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 }
:
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.
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.
in dit geval gaat de vernietiging door met:
dus als u wilt dat x
123 is als het object of de eigenschap ontbreekt, moet u een standaardwaarde opgeven voor x
zelf:
hier gaat de vernietiging als volgt verder, ongeacht of de rechterkant of
is.
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.:
u kunt ook eigenschapswaarde stenografisch combineren met standaardwaarden:
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:
Berekend eigendom toetsen kunt u destructure eigenschappen waarvan de sleutels zijn symbolen:
10.7 Meer Array destructuring features #
10.7.1 Elision #
Elision kun je de syntaxis van de Array “gaten” overslaan elementen tijdens destructuring:
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:
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::
de operand van de rest operator hoeft geen variabele te zijn, je kunt ook patronen gebruiken:
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
):
of een verwijzing naar een Array-element (arr
):
u kunt ook objecteigenschappen en Array-elementen toewijzen via de rest-operator (...
):
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:
De work-around is om de volledige expressie tussen haakjes:
De volgende syntaxis werkt niet:
Met let
, var
en const
, accolades nooit de oorzaak zijn van problemen:
10.10 voorbeelden van vernietiging #
laten we beginnen met een paar kleinere voorbeelden.
de for-of
lus ondersteunt de vernietiging:
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:
10.10.1 Destructuring retourneerde Arrays #
sommige ingebouwde JavaScript-bewerkingen retourneren Arrays. Vernietigen helpt bij het verwerken ervan:
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:
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:
Array.prototype.split()
geeft een Array terug. Daarom is vernietiging nuttig als je geïnteresseerd bent in de elementen, niet in de Array:
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.
10.10.3 Array-destructuring iterbare waarden #
Array-destructuring werkt met elke iterbare waarde. Dat is soms nuttig:
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
true
retourneert. 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.
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()
:
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.:
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.
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.
10.11.1 het algoritme #
een destructieopdracht ziet er als volgt uit:
we willen pattern
gebruiken om gegevens uit value
te 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:
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
- (2e)
{} ← obj
(geen eigenschappen links)
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
(inclusiefundefined
ennull
)
10.11.1.3 Object patroon #
- (2a)
{"properties"} ← undefined
- (2b)
{"properties"} ← null
- (2c)
{key: "pattern", "properties"} ← obj
- (2d)
{key: "pattern" = default_value, "properties"} ← obj
- (2e)
{} ← obj
(geen eigenschappen links)
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))
- (3b)
← iterable
assert(isIterable(iterable))
Helper functie:
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
- (3d)
"pattern" = default_value, "elements" ← iterator
- (3e)
, "elements" ← iterator
(gat, elision)
- (3f)
..."pattern" ← iterator
(altijd laatste deel!)
- (3g)
← iterator
(geen elementen links)
Helper functie:
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
:
er zijn drie standaardwaarden in regel A:
- met de eerste twee standaardwaarden kunt u
x
eny
weglaten. - 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?
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.
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):
de linkerkant bevat eigenschap waarde Afkorting, het is een afkorting voor:
deze vernietiging leidt tot de volgende twee opdrachten (regels 2c, 1):
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):
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):
de linkerkant bevat eigenschapswaarde Steno ‘ s, wat betekent dat deze vernietiging gelijk is aan:
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):
Dat leidt tot de volgende opdrachten (regel 1):
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):
zoals in Voorbeeld 1, zijn er geen eigenschappen x
en y
aan de rechterkant en worden de standaardwaarden gebruikt:
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.