10. Destructurare

10. Destructurare #

  • 10.1. Prezentare generală
    • 10.1.1. Destructurarea obiectului
    • 10.1.2. Destructurarea matricei
    • 10.1.3. Unde poate fi folosită distrugerea?
  • 10.2. Context: construirea datelor versus extragerea datelor
  • 10.3. Modele pentru destructurarea
    • 10.3.1. Alege ceea ce ai nevoie
  • 10.4. Cum accesează modelele măruntaiele valorilor?
    • 10.4.1. Modelele de obiecte constrâng valori la obiecte
    • 10.4.2. Modelele de matrice funcționează cu iterabile
  • 10.5. Valori implicite
    • 10.5.1. undefined declanșează valorile implicite
    • 10.5.2. Valorile implicite sunt calculate la cerere
    • 10.5.3. Valorile implicite se pot referi la alte variabile din modelul
    • 10.5.4. Valori implicite pentru modele
    • 10.5.5. Valori implicite mai complexe
  • 10.6. Mai multe caracteristici de distrugere a obiectelor
    • 10.6.1. Stenogramele valorii proprietății
    • 10.6.2. Chei de proprietate calculate
  • 10.7. Mai multe caracteristici de destructurare a matricei
    • 10.7.1. Eliziune
    • 10.7.2. Operator de odihnă(...)
  • 10.8. Puteți atribui mai mult decât variabile
  • 10.9. Capcanele distrugerii
    • 10.9.1. Nu începeți o declarație cu o bretele cret
  • 10.10. Exemple de destructurare
    • 10.10.1. Destructurarea tablourilor returnate
    • 10.10.2. Distrugerea obiectelor returnate
    • 10.10.3. Array-destructuring valori iterabile
    • 10.10.4. Mai multe valori de returnare
  • 10.11. Algoritmul de destructurare
    • 10.11.1. Algoritmul
    • 10.11.2. Aplicarea algoritmului

10.1 Prezentare generală #

destructurarea este o modalitate convenabilă de a extrage mai multe valori din datele stocate în obiecte și matrice (eventual imbricate). Poate fi utilizat în locații care primesc date (cum ar fi partea stângă a unei sarcini). Modul de extragere a valorilor este specificat prin modele (citiți mai departe pentru exemple).

10.1.1 destructurarea obiectelor #

destructurarea obiectelor:

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'

destructurarea ajută la procesarea valorilor returnate:

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

10.1.2 Array destructuring #

array destructuring (funcționează pentru toate valorile iterabile):

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

destructurarea ajută la procesarea valorilor returnate:

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

10.1.3 unde poate fi folosită distrugerea? #

destructurarea poate fi utilizată în următoarele locații (afișez modele de matrice pentru a demonstra; modelele de obiecte funcționează la fel de bine):

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

de asemenea, puteți destructura într-o buclă for-of :

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

10.2 context: construirea datelor versus extragerea datelor #

pentru a înțelege pe deplin ce este destructurarea, să examinăm mai întâi contextul său mai larg.

JavaScript are operațiuni pentru construirea de date, o proprietate la un moment dat:

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

aceeași sintaxă poate fi utilizată pentru a extrage date. Din nou, o proprietate la un moment dat:

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

în plus, există sintaxă pentru a construi mai multe proprietăți în același timp, printr-un obiect literal:

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

înainte de ES6, nu exista un mecanism corespunzător pentru extragerea datelor. Asta este destructurarea – vă permite să extrageți mai multe proprietăți dintr-un obiect printr-un model de obiect. De exemplu, în partea stângă a unei misiuni:

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

de asemenea, puteți destructura matrice prin modele:

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

10.3 modele pentru destructurare #

următoarele două părți sunt implicate în destructurare:

  • sursa de distrugere: datele care trebuie distruse. De exemplu, partea dreaptă a unei misiuni de distrugere.
  • țintă de destructurare: modelul folosit pentru destructurare. De exemplu, partea stângă a unei misiuni de distrugere.

ținta destructurantă este unul dintre cele trei modele:

  • țintă de atribuire. De exemplu: x
    • o țintă de atribuire este de obicei o variabilă. Dar în destructuring cesiune, aveți mai multe opțiuni, așa cum voi explica mai târziu.
  • model de obiect. De exemplu: { first: "pattern", last: "pattern" }
    • părțile unui model de obiect sunt proprietăți, valorile proprietății sunt din nou modele (recursiv).
  • model de matrice. De exemplu:
    • părțile unui model de matrice sunt elemente, elementele sunt din nou modele (recursiv).

asta înseamnă că poți cuibări modele, în mod arbitrar profund:

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

10.3.1 Alegeți ce aveți nevoie #

dacă destructurați un obiect, menționați numai acele proprietăți care vă interesează:

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

dacă destructurați o matrice, puteți alege să extrageți doar un prefix:

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

10.4 cum accesează modelele măruntaiele valorilor? #

într-o misiune pattern = someValue, cum accesează patternce se află în interiorul someValue?

10.4.1 modelele de obiecte constrâng valorile la obiecte #

modelul obiectului constrânge sursele de distrugere la obiecte înainte de a accesa proprietățile. Asta înseamnă că funcționează cu valori primitive:

const {length : len} = 'abc'; // len = 3const {toString: s} = 123; // s = Number.prototype.toString
10.4.1.1 dacă nu se destructurează obiect o valoare #

constrângerea la obiect nu se realizează prin Object(), ci prin operația internă ToObject(). Cele două operații tratează undefined și null diferit.

Object() convertește valorile primitive la obiecte de înveliș și lasă obiecte neatinse:

> 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

în consecință, puteți utiliza modelul de obiect gol {} pentru a verifica dacă o valoare este coercibilă pentru un obiect. După cum am văzut, doar undefined și null nu sunt:

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

parantezele din jurul expresiilor sunt necesare, deoarece declarațiile nu trebuie să înceapă cu acolade în JavaScript (detaliile sunt explicate mai târziu).

10.4.2 modelele de matrice funcționează cu iterabile #

destructurarea matricei folosește un iterator pentru a ajunge la elementele unei surse. Prin urmare, puteți matrice-destructura orice valoare care este iterabil. Să ne uităm la exemple de valori iterabile.

șirurile sunt iterabile:

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

nu uitați că iteratorul peste șiruri returnează puncte de cod („caractere Unicode”, 21 biți), nu Unități de cod („caractere JavaScript”, 16 biți). (Pentru mai multe informații despre Unicode, consultați capitolul „capitolul 24. Unicode și JavaScript ” în „Vorbind JavaScript”.) De exemplu:

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

nu puteți accesa elementele unui Set prin indici, dar puteți face acest lucru printr-un iterator. Prin urmare, Array destructuring funcționează pentru seturi:

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

iteratorul Set returnează întotdeauna elementele în ordinea în care au fost inserate, motiv pentru care rezultatul distrugerii anterioare este întotdeauna același.

10.4.2.1 nereușind să Destructureze o valoare #

o valoare este iterabilă dacă are o metodă a cărei cheie este Symbol.iterator care returnează un obiect. Array-destructuring aruncă o TypeError dacă valoarea care urmează să fie destructurat nu este iterabil:

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 este aruncat chiar înainte de accesarea elementelor iterabile, ceea ce înseamnă că puteți utiliza modelul matrice gol pentru a verifica dacă o valoare este iterabilă:

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

10.5 valorile implicite #

valorile implicite sunt o caracteristică opțională a modelelor. Ele oferă o rezervă dacă nu se găsește nimic în sursă. Dacă o parte (o proprietate obiect sau un element de matrice) nu are nici o potrivire în sursă, se potrivește cu:

  • valoarea implicită (dacă este specificată; este opțional)
  • undefined (altfel)

să ne uităm la un exemplu. În următoarea destructurare, elementul de la indexul 0 nu are nicio potrivire în partea dreaptă. Prin urmare, destructurarea continuă prin potrivirea x cu 3, ceea ce duce la setarea x la 3.

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

de asemenea, puteți utiliza valori implicite în modelele de obiecte:

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

10.5.1 undefined declanșează valorile implicite #

valorile implicite sunt de asemenea utilizate dacă o parte are o potrivire și acea potrivire este undefined:

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

motivul pentru acest comportament este explicat în capitolul următor, în secțiunea privind valorile implicite ale parametrilor.

10.5.2 valorile implicite sunt calculate la cerere #

valorile implicite în sine sunt calculate numai atunci când sunt necesare. Cu alte cuvinte, această distrugere:

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

este echivalent cu:

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

puteți observa că dacă utilizați 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

cu toate acestea, ordinea contează: variabilele x și y sunt declarate de la stânga la dreapta și produc un ReferenceError dacă sunt accesate înainte de declarațiile lor:

const  = ; // ReferenceError

10.5.4 valori implicite pentru modele #

până acum am văzut doar valori implicite pentru variabile, dar le puteți asocia și cu modele:

const  = ;

ce înseamnă asta? Amintiți-vă regula pentru valorile implicite: dacă o parte nu are nicio potrivire în sursă, destructurarea continuă cu valoarea implicită.

elementul de la indexul 0 nu se potrivește, motiv pentru care destructurarea continuă cu:

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

puteți vedea mai ușor de ce lucrurile funcționează în acest fel dacă înlocuiți modelul { prop: x } cu variabila pattern:

const  = ;

10.5.5 valori implicite mai complexe #

să explorăm în continuare valorile implicite pentru modele. În exemplul următor, atribuim o valoare x prin valoarea implicită { prop: 123 }:

const  = ;

deoarece elementul matrice de la indexul 0 nu are nicio potrivire în partea dreaptă, destructurarea continuă după cum urmează și x este setată la 123.

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

cu toate acestea, x nu i se atribuie o valoare în acest mod dacă partea dreaptă are un element la indexul 0, deoarece atunci valoarea implicită nu este declanșată.

const  = ;

în acest caz, distrugerea continuă cu:

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

astfel, dacă doriți ca x să fie 123 dacă lipsește obiectul sau proprietatea, trebuie să specificați o valoare implicită pentru x în sine:

const  = ;

aici, destructurarea continuă după cum urmează, indiferent dacă partea dreaptă este sau .

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

10.6 mai multe obiecte destructuring caracteristici #

10.6.1 shorthands valoare de proprietate #

shorthands valoare de proprietate sunt o caracteristică a literali obiect: Dacă valoarea proprietății este o variabilă care are același nume ca și cheia proprietății, atunci puteți omite cheia. Acest lucru funcționează și pentru destructurare:

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

de asemenea, puteți combina stenografiile valorii proprietății cu valorile implicite:

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

10.6.2 cheile de proprietate calculate #

cheile de proprietate calculate sunt o altă caracteristică literală a obiectului care funcționează și pentru destructurare. Puteți specifica cheia unei proprietăți printr – o expresie, dacă o puneți între paranteze pătrate:

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

cheile de proprietate calculate vă permit să destructurați proprietățile ale căror chei sunt simboluri:

// 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 mai multe matrice destructuring caracteristici #

10.7.1 elizion #

elizion vă permite să utilizați sintaxa de matrice „găuri” pentru a sări peste elemente în timpul destructuring:

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

10.7.2 operator de odihnă(...) #

operatorul rest vă permite să extrageți elementele rămase ale unui iterabil într-o matrice. Dacă acest operator este utilizat în interiorul unui model de matrice, acesta trebuie să vină ultima:

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

dacă operatorul nu poate găsi niciun element, se potrivește cu operandul său cu matricea goală. Adică nu produce niciodată undefined sau null. De exemplu:

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

operandul operatorului rest nu trebuie să fie o variabilă, puteți utiliza modele, de asemenea:

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

operatorul rest declanșează următoarea destructurare:

 = 

10.8 puteți atribui mai mult decât variabile #

dacă atribuiți prin destructurare, fiecare țintă de atribuire poate fi tot ceea ce este permis în partea stângă a unei sarcini normale.

de exemplu, o referință la o proprietate (obj.prop):

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

sau o referință la un element de matrice(arr):

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

de asemenea, puteți atribui proprietăților obiectului și elementelor de matrice prin intermediul operatorului rest (...):

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

dacă declarați variabile sau definiți parametri prin destructurare, atunci trebuie să utilizați identificatori simpli, nu vă puteți referi la proprietățile obiectului și la elementele matricei.

10.9 capcanele de destructurare #

există două lucruri de care trebuie să fii atent atunci când folosești destructurarea:

  • nu poți începe o declarație cu o bretele cret.
  • în timpul destructurării, puteți declara variabile sau le puteți atribui, dar nu ambele.

următoarele două secțiuni conțin detaliile.

10.9.1 nu începeți o declarație cu o proteză ondulată #

deoarece blocurile de cod încep cu o proteză ondulată, declarațiile nu trebuie să înceapă cu una. Acest lucru este regretabil atunci când se utilizează obiect destructuring într-o misiune:

{ a, b } = someObject; // SyntaxError

lucrarea este de a pune expresia completă între paranteze:

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

următoarea sintaxă nu funcționează:

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

cu let, var și const, bretelele ondulate nu provoacă niciodată probleme:

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

10.10 Exemple de destructurare #

să începem cu câteva exemple mai mici.

bucla for-of suportă destructurarea:

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

puteți utiliza destructurarea pentru a schimba valorile. Acesta este un lucru pe care motoarele l-ar putea optimiza, astfel încât să nu se creeze nicio matrice.

 = ;

puteți utiliza destructurarea pentru a împărți o matrice:

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

10.10.1 destructurarea a revenit matrice #

unele built-in JavaScript operațiuni return matrice. Destructurarea ajută la procesarea acestora:

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

dacă sunteți interesat doar de grupuri (și nu de potrivirea completă, all), puteți utiliza elizion pentru a sări peste elementul matrice la index 0:

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

exec() returnează null dacă expresia regulată nu se potrivește. Din păcate, nu puteți gestiona null prin valori implicite, motiv pentru care trebuie să utilizați operatorul Or (||) în acest caz:

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

Array.prototype.split() returnează o matrice. Prin urmare, destructurarea este utilă dacă sunteți interesat de elemente, nu de matrice:

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

10.10.2 destructurarea obiectelor returnate #

destructurarea este utilă și pentru extragerea datelor din obiecte care sunt returnate prin funcții sau metode. De exemplu, metoda iterator next() returnează un obiect cu două proprietăți, done și value. Următorul cod înregistrează toate elementele matricei arrprin iteratorul iter. Destructurarea este utilizată în linia 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 valori iterabile #

array-destructuring funcționează cu orice valoare iterabilă. Acest lucru este uneori util:

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

10.10.4 valori de returnare Multiple #

pentru a vedea utilitatea valorilor de returnare multiple, să implementăm o funcție findElement(a, p) care caută primul element din matrice a pentru care funcția preturnează true. Întrebarea este: ce ar trebui să se întoarcă findElement()? Uneori cineva este interesat de elementul însuși, alteori de indexul său, alteori de ambele. Următoarea implementare returnează ambele.

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

funcția iterează peste toate elementele array, prin metoda matricei entries(), care returnează un iterabil peste perechi (linia a). Părțile perechilor sunt accesate prin destructurare.

să folosim findElement():

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

mai multe caracteristici ECMAScript 6 ne-au permis să scriem un cod mai concis: apelul invers este o funcție săgeată; valoarea returnată este destructurată printr-un model de obiect cu stenograme ale valorii proprietății.

datorită index și element referindu-se și la cheile de proprietate, ordinea în care le menționăm nu contează. Le putem schimba și nimic nu se schimbă:

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

am gestionat cu succes cazul de a avea nevoie atât de index, cât și de element. Ce se întâmplă dacă suntem interesați doar de unul dintre ei? Se pare că, datorită ECMAScript 6, implementarea noastră poate avea grijă și de asta. Iar cheltuielile sintactice în comparație cu funcțiile cu valori unice de returnare sunt minime.

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

de fiecare dată, extragem doar valoarea unei proprietăți de care avem nevoie.

10.11 algoritmul de destructurare #

această secțiune privește destructurarea dintr-un unghi diferit: ca un algoritm recursiv de potrivire a modelelor.

la final, voi folosi algoritmul pentru a explica diferența dintre următoarele două declarații de funcții.

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

10.11.1 algoritmul #

o misiune de distrugere arată astfel:

"pattern" = "value"

vrem să folosim patternpentru a extrage date din value. Voi descrie acum un algoritm pentru a face acest lucru, care este cunoscut în programarea funcțională ca model de potrivire (scurt: potrivire). Algoritmul specifică operatorul („match against”) pentru destructurarea atribuirii care se potrivește cu un pattern împotriva unui value și se atribuie variabilelor în timp ce face acest lucru:

"pattern"  "value"

algoritmul este specificat prin reguli recursive care separă ambii operanzi ai operatorului . Notația declarativă poate dura ceva obișnuit, dar face ca specificația algoritmului să fie mai concisă. Fiecare regulă are două părți:

  • capul (prima linie) descrie condiția care declanșează regula.
  • corpul (liniile rămase) descrie ce se întâmplă dacă regula este declanșată.

să ne uităm la un exemplu:

  • (2c) {key: "pattern", "properties"} ← obj
     "pattern"  obj.key {"properties"}  obj
  • (2e) {} ← obj (nu au mai rămas proprietăți)
     // Nothing to do

în regula (2C), capul înseamnă că această regulă este executată dacă există un model de obiect cu cel puțin o proprietate și zero sau mai multe proprietăți rămase. Acest model este comparat cu o valoare obj. Efectul acestei reguli este că execuția continuă cu modelul valorii proprietății fiind potrivit cu obj.key și proprietățile rămase fiind potrivite cu obj.

în regula (2e), capul înseamnă că această regulă este executată dacă modelul de obiect gol {}se potrivește cu o valoare obj. Atunci nu este nimic de făcut.

ori de câte ori algoritmul este invocat, regulile sunt verificate de sus în jos și se execută doar prima regulă aplicabilă.

i arată doar algoritmul pentru destructuring atribuire. Destructurarea declarațiilor variabile și destructurarea definițiilor parametrilor funcționează în mod similar.

nu acopăr funcții avansate (chei de proprietate calculate; stenograme ale valorii proprietății; proprietăți obiect și elemente de matrice ca obiective de atribuire), fie. Doar elementele de bază.

10.11.1.1 modele #

un model este fie:

  • o variabilă: x
  • un model de obiect: {"properties"}
  • un model de matrice:

fiecare dintre următoarele secțiuni descrie unul dintre aceste trei cazuri.

următoarele trei secțiuni specifică modul de tratare a acestor trei cazuri. Fiecare secțiune conține una sau mai multe reguli numerotate.

10.11.1.2 variabilă #
  • (1) x ← value (inclusiv undefined și null)
     x = value
10.11.1.3 model de obiect #
  • (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 (nu au mai rămas proprietăți)
     // Nothing to do

10.11.1.4 model Array #

model Array și iterabil. Algoritmul pentru destructurarea matricei începe cu un model de matrice și un iterabil:

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

funcția Helper:

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

elemente Array și iterator. Algoritmul continuă cu elementele modelului (partea stângă a săgeții) și iteratorul care a fost obținut din iterabil (partea dreaptă a săgeții).

  • (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(gaura, eliziune)
     getNext(iterator); // skip "elements"  iterator
  • (3f) ..."pattern" ← iterator( întotdeauna ultima parte!)
     const tmp = ; for (const elem of iterator) { tmp.push(elem); } "pattern"  tmp
  • (3g) ← iterator (nu au mai rămas elemente)
     // Nothing to do

funcția Helper:

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

10.11.2 aplicând algoritmul #

în ECMAScript 6, puteți simula parametrii numiți dacă apelantul folosește un obiect literal și apelatul folosește destructurarea. Această simulare este explicată în detaliu în capitolul privind manipularea parametrilor. Următorul cod arată un exemplu: funcția move1() are doi parametri numiți, x și y:

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

există trei valori implicite în linia A:

  • primele două valori implicite vă permit să omiteți x și y.
  • a treia valoare implicită vă permite să apelați move1() fără parametri (ca în ultima linie).

dar de ce ați defini parametrii ca în fragmentul de cod anterior? De ce nu după cum urmează – care este, de asemenea, codul ES6 complet legal?

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

pentru a vedea de ce move1() este corect, să folosim ambele funcții pentru două exemple. Înainte de a face acest lucru, să vedem cum poate fi explicată trecerea parametrilor prin potrivire.

10.11.2.1 context: trecerea parametrilor prin potrivirea #

pentru apelurile funcționale, parametrii formali (definițiile funcției interioare) sunt potriviți cu parametrii reali (apelurile funcției interioare). De exemplu, luați următoarea definiție a funcției și următorul apel de funcție.

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

parametrii a și b sunt configurați în mod similar cu următoarea destructurare.

  
10.11.2.2 utilizarea move2() #

să examinăm cum funcționează destructurarea pentru move2().

Exemplul 1. move2() duce la această destructurare:

  

elementul matrice unică din partea stângă nu are o potrivire în partea dreaptă, motiv pentru care {x,y} este potrivit cu valoarea implicită și nu cu datele din partea dreaptă (Regulile 3b, 3d):

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

partea stângă conține stenograme de valoare a proprietății, este o abreviere pentru:

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

această destructurare duce la următoarele două sarcini (Regulile 2c, 1):

x = 0;y = 0;

exemplu 2. Să examinăm apelul funcției move2({z:3}) care duce la următoarea destructurare:

  

există un element de matrice la indexul 0 în partea dreaptă. Prin urmare, valoarea implicită este ignorată și următorul pas este (regula 3d):

{x, y}  { z: 3 }

aceasta duce la setarea x și y la undefined, ceea ce nu este ceea ce ne dorim.

10.11.2.3 utilizarea move1() #

să încercăm move1().

exemplu 1: move1()

  

nu avem un element de matrice la indexul 0 din partea dreaptă și folosim valoarea implicită (regula 3d):

{x=0, y=0}  {}

partea stângă conține stenograme ale valorii proprietății, ceea ce înseamnă că această destructurare este echivalentă cu:

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

nici proprietatea x, nici proprietatea y nu au o potrivire în partea dreaptă. Prin urmare, valorile implicite sunt utilizate și următoarele distrugeri sunt efectuate în continuare (regula 2d):

x  0y  0

aceasta duce la următoarele sarcini (regulă 1):

x = 0y = 0

exemplu 2: move1({z:3})

  

primul element al modelului Array are o potrivire în partea dreaptă și acea potrivire este utilizată pentru a continua destructurarea (regula 3d):

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

ca în exemplul 1, nu există proprietăți x și y în partea dreaptă și valorile implicite sunt utilizate:

x = 0y = 0
10.11.2.4 concluzie #

exemplele demonstrează că valorile implicite sunt o caracteristică a pieselor de model (proprietăți obiect sau elemente de matrice). Dacă o parte nu se potrivește sau se potrivește cu undefined, atunci se folosește valoarea implicită. Adică, modelul este potrivit cu valoarea implicită, în schimb.