10. Destructuring
10. Destructuring #
- 10.1. Áttekintés
- 10.1.1. Objektum megsemmisítése
- 10.1.2. Tömb destructuring
- 10.1.3. Hol lehet megsemmisíteni?
- 10.2. Háttér: adatok felépítése az adatok kinyerésével szemben
- 10.3.
- 10.3.1. Válassza ki, amire szüksége van
- 10.4. Hogyan férnek hozzá a minták az értékek belsejéhez?
- 10.4.1. Az objektumminták a
- 10.4.2 objektumokra kényszerítik az értékeket. Array minták dolgozni iterables
- 10.5. Alapértelmezett értékek
- 10.5.1.
undefined
kiváltja az alapértelmezett értékeket - 10.5.2. Az alapértelmezett értékeket igény szerint számítják ki
- 10.5.3. Az alapértelmezett értékek hivatkozhatnak a
- 10.5.4 minta más változóira. Alapértelmezett értékek minták
- 10.5.5. Bonyolultabb alapértelmezett értékek
- 10.5.1.
- 10.6. Több objektum destructuring funkciók
- 10.6.1. Tulajdonságérték rövidítések
- 10.6.2. Számított tulajdonságkulcsok
- 10.7. Több tömb destructuring funkciók
- 10.7.1. Elision
- 10.7.2. Rest operátor (
...
)
- 10.8. A
- 10.9 változókhoz több is rendelhető. A destrukturálás buktatói
- 10.9.1. Ne kezdjen el egy nyilatkozatot göndör merevítővel
- 10.10. Példák a
- 10.10.1. Destructuring vissza tömbök
- 10.10.2. Destructuring visszaadott objektumok
- 10.10.3. Array – destructuring iterable értékek
- 10.10.4. Több visszatérési érték
- 10.11. A destrukturáló algoritmus
- 10.11.1. Az algoritmus
- 10.11.2. Az algoritmus alkalmazása
10.1 Overview #
a Destructuring egy kényelmes módszer több érték kinyerésére a (Esetleg beágyazott) objektumokban és tömbökben tárolt adatokból. Használható olyan helyeken, amelyek adatokat fogadnak (például egy hozzárendelés bal oldalán). Az értékek kibontásának módját a minták határozzák meg (olvassa el a példákat).
10.1.1 objektum megsemmisítése #
objektum megsemmisítése:
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'
a Destrukturálás segít a visszatérési értékek feldolgozásában:
const
obj
=
{
foo
:
123
};
const
{
writable
,
configurable
}
=
Object
.
getOwnPropertyDescriptor
(
obj
,
'foo'
);
console
.
log
(
writable
,
configurable
);
// true true
10.1.2 tömb destructuring #
tömb destructuring (működik az összes iterálható értékek):
const
iterable
=
;
const
=
iterable
;
// x = 'a'; y = 'b'
a Destrukturálás segít a visszatérési értékek feldolgozásában:
const
=
/^(\d\d\d\d)-(\d\d)-(\d\d)$/
.
exec
(
'2999-12-31'
);
10.1.3 hol lehet megsemmisíteni? #
a Destrukturálás a következő helyeken használható (Tömbmintákat mutatok be, hogy bemutassam; az objektumminták ugyanúgy működnek):
// Variable declarations:
const
=
;
let
=
;
var
=
;
// Assignments:
=
;
// Parameter definitions:
function
f
()
{
···
}
f
();
a for-of
hurokban is megsemmisíthető:
const
arr
=
;
for
(
const
of
arr
.
entries
())
{
console
.
log
(
index
,
element
);
}
// Output:
// 0 a
// 1 b
10.2 Háttér: adatok felépítése versus adatok kinyerése #
ahhoz, hogy teljes mértékben megértsük, mi a destrukturálás, először vizsgáljuk meg annak tágabb kontextusát.
a JavaScriptnek vannak műveletei az adatok szerkesztésére, egyszerre egy tulajdonság:
const
obj
=
{};
obj
.
first
=
'Jane'
;
obj
.
last
=
'Doe'
;
ugyanez a szintaxis használható az adatok kinyerésére. Ismét egy ingatlan egy időben:
const
f
=
obj
.
first
;
const
l
=
obj
.
last
;
ezenkívül van szintaxis több tulajdonság egyidejű felépítésére egy objektum literál segítségével:
const
obj
=
{
first
:
'Jane'
,
last
:
'Doe'
};
az ES6 előtt nem volt megfelelő mechanizmus az adatok kinyerésére. Ez az, ami a destrukturálás – lehetővé teszi, hogy több tulajdonságot kivonjon egy objektumból egy objektummintán keresztül. Például egy hozzárendelés bal oldalán:
const
{
first
:
f
,
last
:
l
}
=
obj
;
a tömböket mintákon keresztül is megsemmisítheti:
const
=
;
// x = 'a'; y = 'b'
10.3 minták a megsemmisítéshez #
a következő két fél vesz részt a megsemmisítésben:
- Destrukturáló forrás: a destrukturálandó adatok. Például a destrukturáló hozzárendelés jobb oldala.
- Destrukturáló cél: a destrukturáláshoz használt minta. Például a destrukturáló hozzárendelés bal oldala.
a megsemmisítő cél a Három minta egyike:
- célpont. Például:
x
- a hozzárendelési cél általában változó. De a megsemmisítő feladatnál több lehetőséged van, ahogy később elmagyarázom.
- objektum minta. Például:
{ first: "pattern", last: "pattern" }
- az objektumminta részei tulajdonságok, a tulajdonságértékek ismét minták (rekurzív módon).
- Array minta. Például:
- a Tömbminta részei elemek, az elemek ismét minták (rekurzív módon).
ez azt jelenti, hogy fészkelhet mintákat, önkényesen mélyen:
const
obj
=
{
a
:
,
b
:
true
};
const
{
a
:
}
=
obj
;
// f = 123
10.3.1 Válassza ki, amire szüksége van #
ha megsemmisít egy objektumot, csak azokat a tulajdonságokat említi, amelyek érdeklik:
const
{
x
:
x
}
=
{
x
:
7
,
y
:
3
};
// x = 7
ha megsemmisít egy tömböt, dönthet úgy, hogy csak egy előtagot von ki:
const
=
;
// x='a'; y='b';
10.4 hogyan férnek hozzá a minták az értékek belsejéhez? #
egy feladat pattern = someValue
, hogyan működik a pattern
hozzáférés mi van benne someValue
?
10.4.1 az Objektumminták értékeket kényszerítenek az objektumokra #
az objektummintázat a tulajdonságok elérése előtt kikényszeríti a források megsemmisítését az objektumokra. Ez azt jelenti, hogy primitív értékekkel működik:
const
{
length
:
len
}
=
'abc'
;
// len = 3
const
{
toString
:
s
}
=
123
;
// s = Number.prototype.toString
10.4.1.1 az objektum megsemmisítésének elmulasztása #
az objektum kényszerítése nem Object()
– en keresztül történik, hanem a ToObject()
belső műveleten keresztül. A két művelet eltérően kezeli a undefined
és a null
értéket.
Object()
a primitív értékeket burkoló objektumokká alakítja, és a tárgyakat érintetlenül hagyja:
> 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
;
// TypeError
const
{
prop
:
y
}
=
null
;
// TypeError
ennek következtében a {}
üres objektumminta segítségével ellenőrizheti, hogy egy érték kényszeríthető-e egy objektumra. Mint láttuk, csak a undefined
és a null
nem:
({}
=
);
// OK, Arrays are coercible to objects
({}
=
'abc'
);
// OK, strings are coercible to objects
({}
=
undefined
);
// TypeError
({}
=
null
);
// TypeError
a kifejezések körüli zárójelekre azért van szükség, mert az állítások nem kezdődhetnek göndör zárójelekkel a JavaScript-ben (a részleteket később ismertetjük).
10.4.2 Array minták működnek iterables #
Array destructuring használ iterátor, hogy az elemek a forrás. Ezért, akkor tömb-destructure bármilyen értéket, amely iterálható. Nézzük meg az iterálható értékek példáit.
a karakterláncok iterálhatók:
const
=
'abc'
;
// x='a'; y=
ne felejtsük el, hogy a karakterláncok feletti iterátor kódpontokat (“Unicode karakterek”, 21 bit) ad vissza, nem kódegységeket (“JavaScript karakterek”, 16 bit). (Az Unicode-ról további információt a “24.fejezet” fejezetben talál. Unicode és JavaScript “a”beszélő JavaScript” – ben.) Például:
const
=
'a\uD83D\uDCA9c'
;
// x='a'; y='\uD83D\uDCA9'; z='c'
a készlet elemeihez indexeken keresztül nem férhet hozzá, de iterátoron keresztül megteheti. Ezért tömb destructuring működik készletek:
const
=
new
Set
();
// x='a'; y='b';
a Set
iterátor az elemeket mindig a beillesztés sorrendjében adja vissza, ezért az előző destrukturálás eredménye mindig ugyanaz.
10.4.2.1 a #
érték Array-destruktúrájának elmulasztása egy érték iterálható, ha van olyan metódusa, amelynek kulcsa Symbol.iterator
, amely visszaad egy objektumot. Az Array-destructuring TypeError
értéket dob, ha a destrukturálandó érték nem iterálható:
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
a TypeError
még az iterable elemeinek elérése előtt eldobásra kerül, ami azt jelenti, hogy a üres Tömbminta segítségével ellenőrizheti, hogy egy érték iterálható-e:
=
{};
// TypeError, empty objects are not iterable
=
undefined
;
// TypeError, not iterable
=
null
;
// TypeError, not iterable
10.5 alapértelmezett értékek #
Az alapértelmezett értékek a minták opcionális jellemzői. Tartalékot nyújtanak, ha semmi sem található a forrásban. Ha egy résznek (objektumtulajdonságnak vagy Tömbelemnek) nincs egyezése a forrásban, akkor:
- az alapértelmezett érték (ha meg van adva; ez opcionális)
-
undefined
(ellenkező esetben)
nézzünk egy példát. A következő destrukturálás során a 0 index elemének nincs egyezése a jobb oldalon. Ezért a destrukturálás folytatódik a x
3-hoz való illesztésével, ami azt eredményezi, hogy x
3-ra van állítva.
const
=
;
// x = 3; y = undefined
alapértelmezett értékeket is használhat az objektummintákban:
const
{
foo
:
x
=
3
,
bar
:
y
}
=
{};
// x = 3; y = undefined
10.5.1 undefined
triggerek alapértelmezett értékek #
Az alapértelmezett értékek akkor is használatosak, ha egy alkatrésznek van egyezése, és az egyezés undefined
:
const
=
;
// x = 1
const
{
prop
:
y
=
2
}
=
{
prop
:
undefined
};
// y = 2
ennek a viselkedésnek az indoklását a következő fejezetben, a paraméter alapértelmezett értékeiről szóló szakaszban ismertetjük.
10.5.2 Az alapértelmezett értékeket igény szerint számítják ki #
magukat az alapértelmezett értékeket csak akkor számítják ki, amikor szükség van rájuk. Más szavakkal, ez a pusztítás:
const
{
prop
:
y
=
someFunc
()}
=
someValue
;
egyenértékű a:
let
y
;
if
(
someValue
.
prop
===
undefined
)
{
y
=
someFunc
();
}
else
{
y
=
someValue
.
prop
;
}
megfigyelheti, hogy ha használja 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=3
const
=
;
// x=7; y=7
const
=
;
// x=7; y=2
a rend azonban számít: a x
és y
változókat balról jobbra deklaráljuk, és ReferenceError
értéket kapunk, ha a deklarációjuk előtt hozzáférünk hozzájuk:
const
=
;
// ReferenceError
10.5.4 a #
minták alapértelmezett értékei eddig csak a változók alapértelmezett értékeit láttuk, de a mintákhoz is társíthatjuk őket:
const
=
;
ez mit jelent? Hívja fel az alapértelmezett értékek szabályát: ha egy résznek nincs egyezése a forrásban, a destrukturálás az alapértelmezett értékkel folytatódik.
a 0 index elemének nincs egyezése, ezért a destrukturálás folytatódik:
const
{
prop
:
x
}
=
{};
// x = undefined
könnyebben láthatja, miért működnek így a dolgok, ha a { prop: x }
mintát a változóra cseréli pattern
:
const
=
;
10.5.5 bonyolultabb alapértelmezett értékek #
vizsgáljuk meg tovább a minták alapértelmezett értékeit. A következő példában értéket rendelünk a x
– hez az alapértelmezett { prop: 123 }
értéken keresztül:
const
=
;
mivel a 0 indexben lévő tömb elemnek nincs egyezése a jobb oldalon, a destrukturálás a következőképpen folytatódik, és a x
értéke 123.
const
{
prop
:
x
}
=
{
prop
:
123
};
// x = 123
azonban a x
nem kap értéket ilyen módon, ha a jobb oldalon van egy elem a 0 Indexnél, mert akkor az alapértelmezett érték nem aktiválódik.
const
=
;
ebben az esetben a destrukturálás folytatódik:
const
{
prop
:
x
}
=
{};
// x = undefined
így, ha azt szeretné, hogy a x
123 legyen, ha az objektum vagy a tulajdonság hiányzik, meg kell adnia egy alapértelmezett értéket magának a x
– nek:
const
=
;
itt a destrukturálás a következőképpen folytatódik, függetlenül attól, hogy a jobb oldali vagy
.
const
{
prop
:
x
=
123
}
=
{};
// x = 123
10.6 további objektum destructuring funkciók #
10.6.1 tulajdonságérték rövidítések #
tulajdonságérték rövidítések az objektum literálok jellemzői: Ha a tulajdonság értéke olyan változó, amelynek neve megegyezik a tulajdonságkulccsal, akkor elhagyhatja a kulcsot. Ez a destrukturáláshoz is működik:
const
{
x
,
y
}
=
{
x
:
11
,
y
:
8
};
// x = 11; y = 8
// Same as:
const
{
x
:
x
,
y
:
y
}
=
{
x
:
11
,
y
:
8
};
a tulajdonságérték rövidítéseket az alapértelmezett értékekkel is kombinálhatja:
const
{
x
,
y
=
1
}
=
{};
// x = undefined; y = 1
10.6.2 számított tulajdonságkulcsok #
a számított tulajdonságkulcsok egy másik objektum-szó szerinti funkció, amely szintén működik a destrukturáláshoz. A tulajdonság kulcsát kifejezéssel adhatja meg, ha szögletes zárójelbe teszi:
const
FOO
=
'foo'
;
const
{
:
f
}
=
{
foo
:
123
};
// f = 123
a számított tulajdonságkulcsok lehetővé teszik olyan tulajdonságok megsemmisítését, amelyek kulcsai szimbólumok:
// Create and destructure a property whose key is a symbol
const
KEY
=
Symbol
();
const
obj
=
{
:
'abc'
};
const
{
:
x
}
=
obj
;
// x = 'abc'
// Extract Array.prototype
const
{
:
func
}
=
;
console
.
log
(
typeof
func
);
// function
10.7 több Array destructuring funkciók #
10.7.1 Elision #
Elision segítségével a szintaxis tömb “lyukak”, hogy kihagyja elemek alatt destructuring:
const
=
;
// x = 'c'; y = 'd'
10.7.2 Rest operátor (...
) #
a rest operátor lehetővé teszi az iterable fennmaradó elemeinek kivonását egy tömbbe. Ha ezt az operátort egy Tömbminta belsejében használják, akkor utolsónak kell lennie:
const
=
;
// x='a'; y=
ha az operátor nem talál semmilyen elemet, akkor az operandusát az üres tömbhöz illeszti. Vagyis soha nem termel undefined
vagy null
értéket. Például:
const
=
;
// x='a'; y=undefined; z=
a rest operátor operandusának nem kell változónak lennie, használhat mintákat is:
const
]
=
;
// x = 'a'; y = 'b'; z = 'c'
a rest operátor a következő megsemmisítést indítja el:
=
10.8 nem csak a #
változókhoz rendelhet hozzá, ha destrukturálással rendel hozzá, minden hozzárendelési cél lehet minden, ami megengedett a normál hozzárendelés bal oldalán.
például egy tulajdonságra való hivatkozás (obj.prop
):
const
obj
=
{};
({
foo
:
obj
.
prop
}
=
{
foo
:
123
});
console
.
log
(
obj
);
// {prop:123}
vagy hivatkozás egy tömb elemre (arr
):
const
arr
=
;
({
bar
:
arr
}
=
{
bar
:
true
});
console
.
log
(
arr
);
//
objektum tulajdonságokhoz és Tömbelemekhez is rendelhető A rest operátoron keresztül (...
):
const
obj
=
{};
=
;
// first = 'a'; obj.prop =
ha változókat deklarál vagy paramétereket definiál destrukturálással, akkor egyszerű azonosítókat kell használnia, nem hivatkozhat az objektum tulajdonságaira és a tömb elemeire.
10.9 A destrukturálás buktatói #
két dolgot kell figyelembe venni a destrukturálás használatakor:
- nem kezdhetsz egy nyilatkozatot egy göndör merevítővel.
- a destrukturálás során deklarálhat változókat, vagy hozzárendelhet hozzájuk, de nem mindkettőt.
a következő két szakasz tartalmazza a részleteket.
10.9.1 ne indítson el egy utasítást göndör zárójel #
mivel a kódblokkok göndör zárójelgel kezdődnek, az utasítások nem kezdődhetnek eggyel. Ez nem szerencsés, ha objektum destructuring egy feladat:
{
a
,
b
}
=
someObject
;
// SyntaxError
a megkerülés az, hogy a teljes kifejezést zárójelbe tegye:
({
a
,
b
}
=
someObject
);
// OK
a következő szintaxis nem működik:
({
a
,
b
})
=
someObject
;
// SyntaxError
let
, var
és const
esetén a göndör zárójelek soha nem okoznak problémát:
const
{
a
,
b
}
=
someObject
;
// OK
10.10 példa a destrukturálásra #
kezdjük néhány kisebb példával.
a for-of
hurok támogatja a megsemmisítést:
const
map
=
new
Map
().
set
(
false
,
'no'
).
set
(
true
,
'yes'
);
for
(
const
of
map
)
{
console
.
log
(
key
+
' is '
+
value
);
}
használhatja destructuring swap értékeket. Ez olyasmi, amit a motorok optimalizálhatnak, így nem jön létre tömb.
=
;
a destrukturálás segítségével feloszthat egy tömböt:
const
=
;
// first = 'a'; rest =
10.10.1 Destructuring visszaadott tömbök #
néhány beépített JavaScript művelet visszatér tömböket. A Destructuring segít a feldolgozásban:
const
=
/^(\d\d\d\d)-(\d\d)-(\d\d)$/
.
exec
(
'2999-12-31'
);
ha csak a csoportok érdekelnek (és nem a Teljes egyezés, all
), akkor az elision segítségével kihagyhatja a tömb elemet az indexben 0:
const
=
/^(\d\d\d\d)-(\d\d)-(\d\d)$/
.
exec
(
'2999-12-31'
);
exec()
visszaadja a null
értéket, ha a reguláris kifejezés nem egyezik. Sajnos nem tudja kezelni a null
értéket alapértelmezett értékekkel, ezért ebben az esetben az Or operátort (||
) kell használnia:
const
=
/^(\d\d\d\d)-(\d\d)-(\d\d)$/
.
exec
(
someStr
)
||
;
Array.prototype.split()
egy tömböt ad vissza. Ezért a destrukturálás akkor hasznos, ha az elemek érdeklik, nem pedig a tömb:
const
cells
=
'Jane\tDoe\tCTO'
const
=
cells
.
split
(
'\t'
);
console
.
log
(
firstName
,
lastName
,
title
);
10.10.2 destructuring visszaadott objektumok #
Destructuring is hasznos adatok kinyerésére objektumok által visszaadott funkciók vagy módszerek. Például a next()
iterátor metódus két tulajdonsággal rendelkező objektumot ad vissza, done
és value
. A következő kód naplózza a arr
tömb összes elemét a iter
iterátoron keresztül. A destrukturálást az a sorban használják.
const
arr
=
;
const
iter
=
arr
();
while
(
true
)
{
const
{
done
,
value
}
=
iter
.
next
();
// (A)
if
(
done
)
break
;
console
.
log
(
value
);
}
10.10.3 Array – destructuring iterable values #
Array-destructuring működik minden iterálható értéket. Ez néha hasznos:
const
=
new
Set
().
add
(
'a'
).
add
(
'b'
);
// x = 'a'; y = 'b'
const
=
'foo'
;
// a = 'f'; b = 'o'
10.10.4 többszörös visszatérési értékek #
a többszörös visszatérési értékek hasznosságának megtekintéséhez hajtsunk végre egy findElement(a, p)
függvényt, amely a a
tömb első elemét keresi, amelyre a p
függvény true
értéket ad vissza. A kérdés az, hogy mit kell findElement()
visszatérni? Néha maga az elem érdekli, néha az indexében, néha mindkettőben. A következő megvalósítás mindkettőt visszaadja.
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
};
}
a függvény a array
összes elemére iterál, a tömb módszer entries()
, amely pár felett iterálható értéket ad vissza (A vonal). A párok részei destrukturálással érhetők el.
használjuk findElement()
:
const
arr
=
;
const
{
element
,
index
}
=
findElement
(
arr
,
x
=>
x
%
2
===
0
);
// element = 8, index = 1
számos ECMAScript 6 funkciók lehetővé tette számunkra, hogy írjon tömörebb kódot: a visszahívás egy nyíl funkció; a visszatérési érték destructured keresztül objektum minta tulajdonság értéke rövidítések.
mivel a index
és element
tulajdonkulcsokra is utal, nem számít, hogy milyen sorrendben említjük őket. Cserélhetjük őket, és semmi sem változik:
const
{
index
,
element
}
=
findElement
(
···
);
sikeresen kezeltük mind az index, mind az elem szükségességét. Mi van, ha csak az egyik érdekel minket? Kiderült, hogy az ECMAScript 6-nak köszönhetően a mi implementációnk erre is képes. A szintaktikai rezsi az egyszeri visszatérési értékekkel rendelkező függvényekhez képest minimális.
const
a
=
;
const
{
element
}
=
findElement
(
a
,
x
=>
x
%
2
===
0
);
// element = 8
const
{
index
}
=
findElement
(
a
,
x
=>
x
%
2
===
0
);
// index = 1
minden alkalommal csak annak a tulajdonságnak az értékét vonjuk ki, amelyre szükségünk van.
10.11 a destrukturáló algoritmus #
ez a szakasz a destrukturálást más szögből vizsgálja: rekurzív mintaillesztési algoritmusként.
a végén az algoritmust használom a következő két függvénydeklaráció közötti különbség magyarázatára.
function
move
({
x
=
0
,
y
=
0
}
=
{})
{
···
}
function
move
({
x
,
y
}
=
{
x
:
0
,
y
:
0
})
{
···
}
10.11.1 az algoritmus #
a destrukturáló hozzárendelés így néz ki:
"
pattern
"
=
"
value
"
a pattern
– et akarjuk használni az adatok kinyerésére a value
– ból. Most leírok egy algoritmust erre, amelyet a funkcionális programozásban mintaillesztésként ismerünk (rövid: illesztés). Az algoritmus meghatározza a ←
operátort (“match against”) a pattern
– nek a value
– nak megfelelő destrukturálási hozzárendeléshez, és ennek során változókhoz rendel:
"
pattern
"
←
"
value
"
az algoritmust olyan rekurzív szabályok határozzák meg, amelyek elválasztják a ←
operátor mindkét operandusát. A deklaratív jelölés némi megszokást igényelhet, de tömörebbé teszi az algoritmus specifikációját. Minden szabálynak két része van:
- a fej (első sor) leírja a szabályt kiváltó feltételt.
- a törzs (fennmaradó sorok) leírja, hogy mi történik, ha a szabály aktiválódik.
nézzünk meg egy példát:
- (2c)
{key: "pattern", "properties"} ← obj
"
pattern
"
←
obj
.
key
{
"
properties
"
}
←
obj
- (2e)
{} ← obj
(nem maradt ingatlan)
// Nothing to do
a (2C) szabályban a fej azt jelenti, hogy ez a szabály akkor kerül végrehajtásra, ha van egy objektumminta, amelynek legalább egy tulajdonsága van, és nulla vagy több megmaradt tulajdonsága van. Ez a minta egy obj
értékkel egyezik meg. Ennek a szabálynak az a hatása, hogy a végrehajtás a tulajdonságérték-minta obj.key
, a fennmaradó tulajdonságok pedig obj
– hez illesztésével folytatódik.
a (2e) szabályban a fej azt jelenti, hogy ez a szabály akkor kerül végrehajtásra, ha a {}
üres objektummintát egy obj
értékkel párosítják. Akkor nincs mit tenni.
az algoritmus meghívásakor a szabályok felülről lefelé kerülnek ellenőrzésre, és csak az első alkalmazható szabály kerül végrehajtásra.
csak a destrukturáló hozzárendelés algoritmusát mutatom be. A változó deklarációk és a paraméterdefiníciók destrukturálása hasonlóan működik.
nem terjed ki a speciális funkciók (számított tulajdonságkulcsok; tulajdonságérték rövidítések; objektumtulajdonságok és tömbelemek mint hozzárendelési célok). Csak az alapokat.
10.11.1.1 minták #
a minta vagy:
- egy változó:
x
- egy objektum minta:
{"properties"}
- egy tömb minta:
a következő szakaszok mindegyike e három eset egyikét írja le.
a következő három szakasz meghatározza, hogyan kell kezelni ezt a három esetet. Minden szakasz egy vagy több számozott szabályt tartalmaz.
10.11.1.2 változó #
- (1)
x ← value
(beleértve aundefined
ésnull
)
x
=
value
10.11.1.3 objektum minta #
- (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
(nem maradt ingatlan)
// Nothing to do
10.11.1.4 Array pattern #
Array pattern és iterable. Az algoritmus a tömb destructuring kezdődik egy tömb minta és egy iterable:
- (3a)
← non_iterable
assert(!isIterable(non_iterable))
throw
new
TypeError
();
- (3b)
← iterable
assert(isIterable(iterable))
const
iterator
=
iterable
();
"
elements
"
←
iterator
segítő funkció:
function
isIterable
(
value
)
{
return
(
value
!==
null
&&
typeof
value
===
'object'
&&
typeof
value
===
'function'
);
}
Array elemek és iterátor. Az algoritmus a minta elemeivel (a nyíl bal oldala) és az iterátorral folytatódik, amelyet az iterable-ből (a nyíl jobb oldala) kaptunk.
- (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
(lyuk, elision)
getNext
(
iterator
);
// skip
"
elements
"
←
iterator
- (3f)
..."pattern" ← iterator
(mindig az utolsó rész!)
const
tmp
=
;
for
(
const
elem
of
iterator
)
{
tmp
.
push
(
elem
);
}
"
pattern
"
←
tmp
- (3G)
← iterator
(nincs elem maradt)
// Nothing to do
segítő funkció:
function
getNext
(
iterator
)
{
const
{
done
,
value
}
=
iterator
.
next
();
return
(
done
?
undefined
:
value
);
}
10.11.2 a #
algoritmust alkalmazva az ECMAScript 6-ban szimulálhatja a megnevezett paramétereket, ha a hívó objektum literált használ, a hívó pedig destrukturálást használ. Ezt a szimulációt részletesen a paraméterkezelésről szóló fejezet ismerteti. A következő kód egy példát mutat: a move1()
függvénynek két megnevezett paramétere van, x
és y
:
function
move1
({
x
=
0
,
y
=
0
}
=
{})
{
// (A)
return
;
}
move1
({
x
:
3
,
y
:
8
});
//
move1
({
x
:
3
});
//
move1
({});
//
move1
();
//
három alapértelmezett érték van az a sorban:
- az első két alapértelmezett érték lehetővé teszi a
x
és ay
kihagyását. - a harmadik alapértelmezett érték lehetővé teszi a
move1()
paraméterek nélküli hívását (mint az utolsó sorban).
de miért definiálná a paramétereket, mint az előző kódrészletben? Miért nem az alábbiak szerint – ami szintén teljesen legális ES6 kód?
function
move2
({
x
,
y
}
=
{
x
:
0
,
y
:
0
})
{
return
;
}
hogy lássuk, miért helyes a move1()
, használjuk mindkét függvényt két példához. Mielőtt ezt megtennénk, nézzük meg, hogyan magyarázható a paraméterek átadása az illesztéssel.
10.11.2.1 háttér: paraméterek átadása a #
függvényhívások esetén a formális paraméterek (belső függvénydefiníciók) a tényleges paraméterekkel (belső függvényhívások) kerülnek egyeztetésre. Vegyük például a következő függvénydefiníciót és a következő függvényhívást.
function
func
(
a
=
0
,
b
=
0
)
{
···
}
func
(
1
,
2
);
a a
és b
paraméterek a következő destrukturáláshoz hasonlóan vannak beállítva.
←
10.11.2.2 használata move2()
#
vizsgáljuk meg, hogyan működik a destrukturálás move2()
esetén.
1.példa. move2()
ez a pusztításhoz vezet:
←
a bal oldali egyetlen tömb elemnek nincs egyezése a jobb oldalon, ezért az {x,y}
az alapértelmezett értékhez illeszkedik, nem pedig a jobb oldali adatokhoz (3B, 3D szabályok):
{
x
,
y
}
←
{
x
:
0
,
y
:
0
}
a bal oldalon található tulajdonságérték rövidítések, ez a rövidítés:
{
x
:
x
,
y
:
y
}
←
{
x
:
0
,
y
:
0
}
ez a megsemmisítés a következő két hozzárendeléshez vezet (2C szabályok, 1):
x
=
0
;
y
=
0
;
példa 2. Vizsgáljuk meg a move2({z:3})
függvényhívást, amely a következő pusztításhoz vezet:
←
van egy tömb elem a 0 Indexnél a jobb oldalon. Ezért az alapértelmezett értéket figyelmen kívül hagyja, és a következő lépés (3D szabály):
{
x
,
y
}
←
{
z
:
3
}
ez azt eredményezi, hogy mind a x
, mind a y
undefined
értékre van állítva, ami nem az, amit akarunk.
10.11.2.3 használat move1()
#
próbáljuk meg move1()
.
példa 1: move1()
←
a jobb oldali 0 Indexnél nincs tömbelem, és az alapértelmezett értéket használjuk (3D szabály):
{
x
=
0
,
y
=
0
}
←
{}
a bal oldali tulajdonságérték rövidítéseket tartalmaz, ami azt jelenti, hogy ez a megsemmisítés egyenértékű:
{
x
:
x
=
0
,
y
:
y
=
0
}
←
{}
sem a x
, sem a y
tulajdonságnak nincs egyezése a jobb oldalon. Ezért a rendszer Az alapértelmezett értékeket használja, majd a következő destrukturációkat hajtja végre (2D szabály):
x
←
0
y
←
0
ez a következő hozzárendelésekhez vezet (szabály 1):
x
=
0
y
=
0
példa 2: move1({z:3})
←
a Tömbminta első elemének jobb oldalán van egyezés, és ezt az egyezést használják a destrukturálás folytatására (3D szabály):
{
x
=
0
,
y
=
0
}
←
{
z
:
3
}
mint az 1. példában, a jobb oldalon nincsenek x
és y
tulajdonságok, és az alapértelmezett értékeket használják:
x
=
0
y
=
0
10.11.2.4 következtetés #
a példák azt mutatják, hogy az alapértelmezett értékek a mintadarabok (objektumtulajdonságok vagy tömbelemek) jellemzői. Ha egy alkatrésznek nincs egyezése, vagy a undefined
értékkel egyezik, akkor az alapértelmezett érték kerül felhasználásra. Ez azt jelenti, hogy a minta Az alapértelmezett értékhez illeszkedik.