ebben a blogbejegyzésben közelebbről megvizsgáljuk, hogy az ECMAScript specifikáció hogyan látja a JavaScript objektumokat. Különösen a tulajdonságok nem atomikusak a specifikációban, hanem több attribútumból állnak (gondolj mezőkre egy rekordban). Még egy adattulajdonság értéke is tárolódik egy attribútumban!
Tartalomjegyzék:
- az objektumok szerkezete #
- belső rések #
- Tulajdonságkulcsok #
- tulajdonság attribútumok #
- Tulajdonságleírók #
- tulajdonságok leíróinak lekérése #
- új tulajdonságok létrehozása a leírókon keresztül #
- meglévő tulajdonságok megváltoztatása a leírókon keresztül #
- buktató: az örökölt csak olvasható tulajdonságokat nem lehet hozzárendelni a #
- API: tulajdonságleírók #
- esetek használata objektumhoz.getOwnPropertyDescriptors () #
- objektum.getOwnPropertyDescriptors (): tulajdonságok másolása egy objektumba #
- buktató: a super #
- objektum.getOwnPropertyDescriptors (): objektumok klónozása #
az objektumok szerkezete #
az ECMAScript specifikációban egy objektum a következőkből áll:
- belső bővítőhelyek, amelyek olyan tárolóhelyek, amelyek nem érhetők el a JavaScript-ből, csak a specifikációban szereplő műveletekhez.
- tulajdonságok gyűjteménye. Minden tulajdonság hozzárendel egy kulcsot az attribútumokhoz (gondoljon mezőkre egy rekordban).
belső rések #
a specifikáció így írja le a belső réseket (a hangsúly az enyém):
- a belső rések megfelelnek az objektumokhoz társított belső állapotnak, amelyet különböző ECMAScript specifikációs algoritmusok használnak.
- a belső rések nem objektumtulajdonságok,és nem öröklődnek.
- az adott belső rés specifikációtól függően az ilyen állapot értékekből állhat:
- bármely ECMAScript nyelvtípusból vagy
- az adott ECMAScript specifikáció típus értékeiből.
- hacsak kifejezetten másként nem határozzuk meg, a belső résidők az objektum létrehozásának részeként kerülnek kiosztásra, és nem adhatók dinamikusan az objektumhoz.
- eltérő rendelkezés hiányában a belső nyílás kezdeti értéke a
undefined
érték. - a specifikáció különböző algoritmusai olyan objektumokat hoznak létre, amelyek belső résekkel rendelkeznek. Az ECMAScript nyelv azonban nem biztosít közvetlen módot a belső rések objektumhoz való társítására.
- a belső módszereket és a belső réseket ebben a specifikációban dupla szögletes zárójelben szereplő nevek segítségével azonosítjuk
]
.
kétféle belső nyílás létezik:
- Módszerhelyek objektumok manipulálására (tulajdonságok megszerzése, tulajdonságok beállítása stb.)
- Data slots with storage (listed in the table below)
Internal data slot | Type |
---|---|
] |
null | object |
] |
boolean |
] |
List of entries |
Descriptions for these data slots:
Tulajdonságkulcsok #
egy tulajdonság kulcsa vagy:
- egy karakterlánc
- egy szimbólum
tulajdonság attribútumok #
kétféle tulajdonság létezik, és különböző attribútumokkal rendelkeznek:
- egy adattulajdonság tárolja az adatokat. Attribútumai
value
bármilyen JavaScript értéket tartalmaz. - egy accessor tulajdonságnak getter és/vagy setter funkciója van. Az előbbit a
get
attribútum tárolja, az utóbbit aset
attribútumban.
az alábbi táblázat felsorolja az összes tulajdonságattribútumot.
Kind of property | Name and type of attribute | Default value |
---|---|---|
Data property | value: any |
undefined |
writable: boolean |
false |
|
Accessor property | get(): any |
undefined |
set(v: any): void |
undefined |
|
All properties | configurable: boolean |
false |
enumerable: boolean |
false |
We have already encountered the attributes value
get
, and set
. The other attributes work as follows:
-
writable
meghatározza, hogy egy adattulajdonság értéke megváltoztatható-e. -
configurable
meghatározza, hogy egy tulajdonság attribútumai megváltoztathatók-e. Hafalse
, akkor:- nem törölheti a tulajdonságot.
- nem módosíthat egy tulajdonságot adattulajdonságról accessor tulajdonságra, vagy fordítva.
- a
value
attribútumon kívül más attribútumot nem lehet megváltoztatni. - azonban még egy attribútum változás megengedett: A
writable
atrue
– rőlfalse
– re változtatható. Ennek az anomáliának az oka Történelmi: a tömbök.length
tulajdonsága mindig írható és nem konfigurálható volt. Awritable
attribútum megváltoztatásának engedélyezése lehetővé teszi a tömbök befagyasztását.
-
enumerable
befolyásol néhány műveletet (példáulObject.assign()
). Hafalse
, akkor ezek a műveletek figyelmen kívül hagyják a tulajdonságot.
Tulajdonságleírók #
a tulajdonságleíró egy tulajdonság attribútumait JavaScript objektumként kódolja. A TypeScript interfészek a következőképpen néznek ki.
a kérdőjelek azt jelzik, hogy minden tulajdonság opcionális. Ha kihagyja a tulajdonságot, amikor egy leírót átad egy műveletnek, akkor az alapértelmezett értéket használja a rendszer.
tulajdonságok leíróinak lekérése #
a következő kód beolvassa az adattulajdonság objektumleíróját first
:
a következő példában lekérjük a getter tulajdonságleíróját fullName
:
a desc()
használatával az a sorban egy megkerülés, így a .deepEqual()
működik.
új tulajdonságok létrehozása a leírókon keresztül #
új tulajdonságokat is létrehozhat a tulajdonságleírókon keresztül:
meglévő tulajdonságok megváltoztatása a leírókon keresztül #
Ha már létezik saját tulajdonság, akkor a leírón keresztül történő definiálás megváltoztatja ezt a tulajdonságot. Egyrészt, amely lehetővé teszi számunkra a Object.defineProperty()
hasonló hozzárendelés használatát:
másrészt használhatjuk a Object.defineProperty()
-t is, hogy egy adattulajdonságot getterré alakítsunk (és fordítva):
buktató: az örökölt csak olvasható tulajdonságokat nem lehet hozzárendelni a #
-hez, ha egy örökölt tulajdonság csak olvasható, akkor nem használhatjuk a hozzárendelést annak megváltoztatására. Az indoklás az, hogy az örökölt tulajdonság felülbírálása saját tulajdonság létrehozásával úgy tekinthető, mint az örökölt tulajdonság roncsolásmentes megváltoztatása. Vitathatatlanul, ha egy tulajdonság nem írható, akkor ezt nem szabad megtennünk.
nézzünk meg egy példát:
nem tudjuk megváltoztatni a tulajdonságot hozzárendeléssel. De még mindig létrehozhatunk saját tulajdonságot annak meghatározásával:
Object.defineProperty(obj, 'prop', {value: 2});assert.equal(obj.prop, 2);
Accessor tulajdonságok, amelyek nem rendelkeznek szetterrel, szintén csak olvashatónak tekinthetők:
API: tulajdonságleírók #
a következő funkciók lehetővé teszik a tulajdonságleírókkal való munkát:
esetek használata objektumhoz.getOwnPropertyDescriptors () #
objektum.getOwnPropertyDescriptors (): tulajdonságok másolása egy objektumba #
az ES6 óta a JavaScript már rendelkezik eszközmódszerrel a tulajdonságok másolásához: Object.assign()
. Ez a módszer azonban egyszerű get és set műveleteket használ egy olyan tulajdonság másolásához, amelynek kulcsa key
:
target = source;
Ez azt jelenti, hogy csak akkor hoz létre hűséges másolatot egy tulajdonságról, ha:
- attribútuma
writable
jelentésetrue
és annak attribútumaenumerable
jelentésetrue
(mert a hozzárendelés így hoz létre tulajdonságokat). - ez egy adat tulajdonság.
a következő példa szemlélteti ezt a korlátozást. Object source
rendelkezik egy szetterrel, amelynek kulcsa data
.
Ha a Object.assign()
tulajdonság másolásához data
, akkor az accessor tulajdonság data
adattulajdonsággá alakul:
szerencsére a Object.getOwnPropertyDescriptors()
együtt Object.defineProperties()
hűségesen másolja a tulajdonság data
:
buktató: a super
#
a super
módszert használó másolási módszerek szorosan kapcsolódnak az otthoni objektumhoz (ahhoz az objektumhoz, amelyben tárolják). Jelenleg nincs mód ilyen módszer másolására vagy áthelyezésére egy másik objektumra.
objektum.getOwnPropertyDescriptors (): objektumok klónozása #
a sekély klónozás hasonló a másolási tulajdonságokhoz, ezért a Object.getOwnPropertyDescriptors()
itt is jó választás.
a klón létrehozásához a Object.create()
: