i dette blogginnlegget ser vi nærmere på Hvordan ECMAScript-spesifikasjonen ser JavaScript-objekter. Spesielt er egenskaper ikke atom i spec, men består av flere attributter (tenk felt i en post). Selv verdien av en dataegenskap er lagret i et attributt!
innholdsfortegnelse:
- strukturen av objekter #
- Interne spor #
- Egenskapsnøkler #
- Egenskapsattributter #
- Egenskapsbeskrivelser #
- Henter beskrivelser for egenskaper #
- Opprette nye egenskaper via beskrivere #
- Endre eksisterende egenskaper via beskrivere #
- Fallgruve: arvede skrivebeskyttede egenskaper kan ikke tilordnes #
- API: property descriptors #
- Use cases For Object.getOwnPropertyDescriptors () #
- Objekt.getOwnPropertyDescriptors (): kopiere egenskaper til et objekt #
- fallgruve: kopieringsmetoder som bruker super #
- Objekt.getOwnPropertyDescriptors(): kloning objekter #
strukturen av objekter #
i ECMAScript-spesifikasjonen består et objekt av:Interne spor, som er lagringssteder som ikke er tilgjengelige Fra JavaScript, bare for operasjoner i spesifikasjonen.
Interne spor #
slik beskriver spesifikasjonen interne spor (vekten er min):
- Interne spor samsvarer med intern tilstand som er knyttet til objekter og brukes av Ulike ecmascript-spesifikasjonsalgoritmer.
- Interne spor er ikke objektegenskaper, og de er ikke arvet.
- avhengig av den spesifikke interne sporspesifikasjonen, kan en slik tilstand bestå av verdier:
- Av En Hvilken Som Helst ECMAScript-språktype eller
- av spesifikke ecmascript-spesifikasjonstypeverdier.
- med mindre annet er uttrykkelig angitt, tildeles interne spor som en del av prosessen med å opprette et objekt og kan ikke legges dynamisk til et objekt.
- med mindre annet er angitt, er den opprinnelige verdien av et internt spor verdien
undefined
. - Ulike algoritmer i denne spesifikasjonen lager objekter som har interne spor. ECMAScript-språket gir imidlertid ingen direkte måte å knytte interne spor til et objekt.Interne metoder og interne spor er identifisert i denne spesifikasjonen ved hjelp av navn som er vedlagt i doble firkantede parenteser
]
.
det finnes to typer interne spor:
- Metodespor for å manipulere objekter (få egenskaper, innstillingsegenskaper, etc.)
- Data slots with storage (listed in the table below)
Internal data slot | Type |
---|---|
] |
null | object |
] |
boolean |
] |
List of entries |
Descriptions for these data slots:
Egenskapsnøkler #
nokkelen til en egenskap er enten:
- en streng
- et symbol
Egenskapsattributter #
det finnes to typer egenskaper og de har forskjellige attributter:
- en dataegenskap lagrer data. Dens attributter
value
har Noen JavaScript-verdi. - en accessor-egenskap har en getter-funksjon og / eller en setter-funksjon. Den tidligere er lagret i attributtet
get
, sistnevnte i attributtetset
.
tabellen nedenfor viser alle egenskapsattributter.
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
bestemmer om verdien av en dataegenskap kan endres. -
configurable
bestemmer om attributtene til en egenskap kan endres. Hvis det erfalse
, så:- du kan ikke slette egenskapen.
- du kan ikke endre en egenskap fra en dataegenskap til en accessor-egenskap eller omvendt.
- du kan ikke endre andre attributter enn
value
. - imidlertid er en endring av attributtet tillatt: Du kan endre
writable
fratrue
tilfalse
. Begrunnelsen bak denne anomali er historisk: Eiendom.length
Av Arrays har alltid vært skrivbar og ikke-konfigurerbar. Ved å tillate atwritable
attributtet endres, kan Vi fryse Arrays.
enumerable
påvirker enkelte operasjoner (for eksempel Object.assign()
). Hvis det er false
, ignorerer disse operasjonene egenskapen.
Egenskapsbeskrivelser #
en egenskapsbeskrivelse koder attributtene til en egenskap som Et JavaScript-objekt. Deres TypeScript-grensesnitt ser ut som følger.
spørsmålstegnene angir at hver egenskap er valgfri. Hvis du utelater en egenskap når du sender en beskrivelse til en operasjon, brukes standardverdien.
Henter beskrivelser for egenskaper #
følgende kode henter objektbeskrivelsen for dataegenskapen first
:
i neste eksempel henter vi egenskapsbeskrivelsen for getter fullName
:
Ved hjelp av desc()
i linje a er et arbeid slik at .deepEqual()
fungerer.
Opprette nye egenskaper via beskrivere #
du kan også opprette nye egenskaper via egenskapsbeskrivere:
Endre eksisterende egenskaper via beskrivere #
hvis en egen egenskap allerede eksisterer, endres den egenskapen ved å definere den via en beskrivende. På den ene siden som tillater oss å bruke Object.defineProperty()
som oppgave:
På den annen side kan vi også brukeObject.defineProperty()
for å slå en dataegenskap til en getter (og omvendt):
Fallgruve: arvede skrivebeskyttede egenskaper kan ikke tilordnes #
Hvis en arvet egenskap er skrivebeskyttet, kan vi ikke bruke oppdrag til å endre den. Begrunnelsen er at det å overstyre en arvet eiendom ved å skape en egen eiendom, kan ses som ikke-destruktivt å endre den arvede eiendommen. Uten tvil, hvis en eiendom ikke er skrivbar, bør vi ikke kunne gjøre det.
La oss se på et eksempel:
vi kan ikke endre eiendommen via oppdrag. Men vi kan fortsatt lage en egen eiendom ved å definere den:
Object.defineProperty(obj, 'prop', {value: 2});assert.equal(obj.prop, 2);
Accessor properties som ikke har en setter, anses også for å være skrivebeskyttet:
API: property descriptors #
følgende funksjoner lar deg jobbe med property descriptors:
Use cases For Object.getOwnPropertyDescriptors () #
Objekt.getOwnPropertyDescriptors (): kopiere egenskaper til et objekt #
Siden ES6 Har JavaScript allerede hatt en verktøymetode for kopiering av egenskaper: Object.assign()
. Denne metoden bruker imidlertid enkle hent og angi operasjoner for å kopiere en egenskap hvis nøkkel er key
:
target = source;
det betyr at den bare oppretter en trofast kopi av en egenskap hvis:
- attributtet
writable
ertrue
og attributtetenumerable
ertrue
(fordi det er slik tildeling oppretter egenskaper). - det er en dataegenskap.
følgende eksempel illustrerer denne begrensningen. Objekt source
har en setter hvis nøkkel er data
.
hvis vi bruker Object.assign()
for å kopiere eiendom data
, konverteres accessor-egenskapen data
til en data-egenskap:
heldigvis bruker Object.getOwnPropertyDescriptors()
div>sammen med Object.defineProperties()
kopierer trofast egenskapen data
:
fallgruve: kopieringsmetoder som bruker super
#
en metode som brukersuper
er godt forbundet med hjemmeobjektet (objektet det er lagret i). Det er for øyeblikket ingen måte å kopiere eller flytte en slik metode til et annet objekt.
Objekt.getOwnPropertyDescriptors(): kloning objekter #
Grunne kloning ligner på kopiering egenskaper, som er grunnen til Object.getOwnPropertyDescriptors()
er et godt valg her, også.
for å lage klonen bruker vi Object.create()
: