v tomto blogu se blíže podíváme na to, jak SPECIFIKACE ECMAScript vidí objekty JavaScriptu. Zejména vlastnosti nejsou ve specifikaci atomové, ale skládají se z více atributů (think fields in a record). Dokonce i hodnota datové vlastnosti je uložena v atributu!
obsah:
- struktura objektů #
- Vnitřní sloty #
- Vlastnost klíče #
- Vlastnosti atributy #
- popisovače vlastností #
- načítání deskriptorů pro vlastnosti #
- Vytvoření nové vlastnosti pomocí popisovačů #
- Změna stávající vlastnosti pomocí popisovačů #
- Úskalí: zděděné vlastnosti jen pro čtení nemůže být přiřazen k #
- API: vlastnost popisovače #
- Využití Objektu.getOwnPropertyDescriptors () #
- objekt.getOwnPropertyDescriptors (): kopírování vlastností do objektu #
- Úskalí: kopírovací metody, které používají super #
- objekt.getOwnPropertyDescriptors(): klonování objektů #
struktura objektů #
ve specifikaci ECMAScript se objekt skládá z:
- interní sloty, což jsou úložiště, která nejsou přístupná z JavaScriptu, pouze pro operace ve specifikaci.
- soubor vlastností. Každá vlastnost přiřazuje klíč s atributy (think fields v záznamu).
Vnitřní sloty #
to je To, jak specifikace popisuje vnitřní sloty (zdůraznění je moje):
- Vnitřní sloty odpovídají vnitřní stav, který je spojen s objekty a používá různé ECMAScript specifikaci algoritmů.
- vnitřní sloty nejsou Vlastnosti objektu a nejsou zděděny.
- v závislosti na konkrétní interní specifikaci slotu může tento stav sestávat z hodnot:
- jakéhokoli typu jazyka ECMAScript nebo
- specifických hodnot typu specifikace ECMAScript.
- Není-li výslovně uvedeno jinak, jsou interní sloty přiděleny jako součást procesu vytváření objektu a nemusí být dynamicky přidávány k objektu.
- pokud není uvedeno jinak, počáteční hodnota interního slotu je hodnota
undefined
. - různé algoritmy v rámci této SPECIFIKACE vytvářejí objekty, které mají vnitřní sloty. Jazyk ECMAScript však neposkytuje žádný přímý způsob, jak spojit interní sloty s objektem.
- interní metody a interní sloty jsou identifikovány v této specifikaci pomocí názvů uzavřených v dvojitých hranatých závorkách
]
.
existují dva druhy vnitřních slotů:
- sloty pro manipulaci s objekty (získávání vlastností, nastavení vlastností atd.)
- Data slots with storage (listed in the table below)
Internal data slot | Type |
---|---|
] |
null | object |
] |
boolean |
] |
List of entries |
Descriptions for these data sloty:
Vlastnost klíče #
klíčové vlastnosti:
- string
- symbol
Vlastnosti atributy #
Existují dva druhy vlastnosti a mají různé atributy:
- vlastnost data ukládá data. Jeho atributy
value
má libovolnou hodnotu JavaScriptu. - vlastnost accessor má funkci getteru a / nebo funkci setteru. Bývalý je uložen v atributu
get
, druhý v atributuset
.
v následující tabulce jsou uvedeny všechny atributy vlastností.
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
určuje, zda lze hodnotu datové vlastnosti změnit. -
configurable
určuje, zda lze atributy vlastnosti změnit. Pokud jefalse
, pak:- vlastnost nelze odstranit.
- vlastnost nelze změnit z datové vlastnosti na vlastnost accessor nebo naopak.
- nelze změnit jiný atribut než
value
. - je však povolena ještě jedna změna atributu: Můžete změnit
writable
ztrue
nafalse
. Důvod této anomálie je historický: vlastnost.length
polí byla vždy zapisovatelná a nenastavitelná. Povolení změny atributuwritable
nám umožňuje zmrazit pole.
-
enumerable
ovlivňuje některé operace (napříkladObject.assign()
). Pokud jefalse
, pak tyto operace vlastnost ignorují.
popisovače vlastností #
popisovač vlastností kóduje atributy vlastnosti jako objekt JavaScript. Jejich rozhraní strojopisu vypadají následovně.
otazníky označují, že každá vlastnost je volitelná. Pokud vynecháte vlastnost při předávání deskriptoru operaci, použije se její výchozí hodnota.
načítání deskriptorů pro vlastnosti #
následující kód načte deskriptor objektu pro datovou vlastnost first
:
V následujícím příkladu, získáme vlastnost deskriptor pro getter fullName
:
Pomocí desc()
v souladu se to obejít tak, že .deepEqual()
funguje.
Vytvoření nové vlastnosti pomocí popisovačů #
můžete také vytvořit nové vlastnosti prostřednictvím majetku deskriptory:
Změna stávající vlastnosti pomocí popisovačů #
Pokud vlastní majetek již existuje, pak definují pomocí deskriptorů změny, které majetek. Na jedné straně nám to umožňuje použít Object.defineProperty()
jako přiřazení:
Na druhou stranu, můžeme také použít Object.defineProperty()
zapnout vlastnost data do getter (a naopak):
Úskalí: zděděné vlastnosti jen pro čtení nemůže být přiřazen k #
Pokud zděděný majetek je jen pro čtení, pak nemůžeme použít úkol to změnit. Důvodem je, že přepsání zděděného majetku vytvořením vlastního majetku lze považovat za nedestruktivně měnící zděděný majetek. Pravděpodobně, pokud vlastnost je non-zapisovatelný, neměli bychom být schopni to udělat.
podívejme se na příklad:
nemůžeme změnit vlastnost pomocí přiřazení. Ale stále můžeme vytvořit vlastní majetek tím, že definuje, že:
Object.defineProperty(obj, 'prop', {value: 2});assert.equal(obj.prop, 2);
Přístupový objekt vlastnosti, které nemají setter je také považován za jen pro čtení:
API: vlastnost popisovače #
následující funkce umožňují pracovat s vlastností deskriptory:
Využití Objektu.getOwnPropertyDescriptors () #
objekt.getOwnPropertyDescriptors (): kopírování vlastností do objektu #
od ES6 má JavaScript již nástroj pro kopírování vlastností: Object.assign()
. Nicméně, tato metoda používá jednoduché získat a nastavit operace pro kopírování majetek, jehož klíč je key
:
target = source;
to znamená, Že pouze vytváří věrnou kopii majetku, pokud:
- Jeho atribut
writable
true
a jeho atributenumerable
true
(protože to je to, jak úkol vytváří vlastnosti). - Jedná se o datovou vlastnost.
následující příklad ilustruje toto omezení. Objekt source
má nastavovač, jehož klíč je data
.
Pokud budeme používat Object.assign()
kopírovat vlastnost data
, pak accessor vlastnost data
je převeden na data vlastnost:
Naštěstí, pomocí Object.getOwnPropertyDescriptors()
Object.defineProperties()
má věrně kopírovat vlastnost data
:
Úskalí: kopírovací metody, které používají super
#
metoda, která se používá super
je pevně spojen s jeho domů objektu (objekt je uložen v). V současné době neexistuje způsob, jak zkopírovat nebo přesunout takovou metodu na jiný objekt.
objekt.getOwnPropertyDescriptors(): klonování objektů #
Mělké klonování je podobný kopírovacímu vlastnosti, což je důvod, proč Object.getOwnPropertyDescriptors()
je dobrá volba, taky.
pro vytvoření klonu používáme Object.create()
: