Maybaygiare.org

Blog Network

Attributter for objektegenskaber i JavaScript

i dette blogindlæg ser vi nærmere på, hvordan ECMAScript-specifikationen ser JavaScript-objekter. Især er egenskaber ikke atomiske i specifikationen, men sammensat af flere attributter (tænk felter i en post). Selv værdien af en dataegenskab gemmes i en attribut!

Indholdsfortegnelse:

strukturen af objekter #

i ECMAScript-specifikationen består et objekt af:

  • interne slots, som er lagerpladser, der ikke er tilgængelige fra JavaScript, kun til operationer i specifikationen.
  • en samling af ejendomme. Hver egenskab knytter en nøgle til attributter (tænk felter i en post).

interne slots #

sådan beskriver specifikationen interne slots (vægten er min):

  • interne slots svarer til intern tilstand, der er forbundet med objekter og bruges af forskellige ECMAScript-specifikationsalgoritmer.
  • interne slots er ikke objektegenskaber, og de arves ikke.
  • afhængigt af den specifikke interne slotspecifikation kan en sådan tilstand bestå af værdier:
    • af enhver ECMAScript-sprogtype eller
    • af specifikke ECMAScript-specifikationstypeværdier.
  • medmindre andet udtrykkeligt er angivet, tildeles interne slots som en del af processen med at oprette et objekt og føjes muligvis ikke dynamisk til et objekt.
  • medmindre andet er angivet, er den oprindelige værdi af en intern slot værdien undefined.
  • forskellige algoritmer inden for denne specifikation skaber objekter, der har interne slots. ECMAScript-sproget giver dog ingen direkte måde at knytte interne slots til et objekt.
  • interne metoder og interne slots identificeres inden for denne specifikation ved hjælp af navne vedlagt i dobbelt firkantede parenteser].

Der er to slags interne slots:

  • metode slots til manipulation af objekter (få egenskaber, indstilling egenskaber, 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:

Egenskabsnøgler #

nøglen til en ejendom er enten:

  • en streng
  • et symbol

Egenskabsattributter #

der er to slags egenskaber, og de har forskellige attributter:

  • en dataejendom gemmer data. Dens attributter value har enhver JavaScript-værdi.
  • en accessoregenskab har en getter-funktion og/eller en setter-funktion. Førstnævnte er gemt i attributten get, sidstnævnte i attributten set.

følgende tabel viser alle egenskabsattributter.

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 valueget, and set. The other attributes work as follows:

  • writable bestemmer, om værdien af en dataegenskab kan ændres.
  • configurable bestemmer, om attributterne for en egenskab kan ændres. Hvis det er false, så:
    • du kan ikke slette ejendommen.
    • du kan ikke ændre en egenskab fra en dataegenskab til en accessoregenskab eller omvendt.
    • du kan ikke ændre nogen anden attribut endvalue.
    • dog er en yderligere attributændring tilladt: Du kan ændre writablefratruetilfalse. Begrundelsen bag denne anomali er historisk: ejendom .length af Arrays har altid været skrivbar og ikke-konfigurerbar. Hvis du tillader, at attributten writable ændres, kan vi fryse Arrays.
  • enumerable påvirker nogle operationer (såsomObject.assign()). Hvis det er false, ignorerer disse operationer ejendommen.

Ejendomsdeskriptorer #

en ejendomsdeskriptor koder attributterne for en ejendom som et JavaScript-objekt. Deres TypeScript-grænseflader ser ud som følger.

spørgsmålstegnene angiver, at hver egenskab er valgfri. Hvis du udelader en egenskab, når du sender en deskriptor til en handling, bruges dens standardværdi.

henter deskriptorer for egenskaber #

følgende kode henter objektbeskrivelsen for dataegenskaben first:

i det næste eksempel henter vi Ejendomsbeskrivelsen for getterfullName:

Ved hjælp afdesc()i linje A er en arbejde rundt, så.deepEqual() virker.

oprettelse af nye egenskaber via deskriptorer #

Du kan også oprette nye egenskaber via ejendomsdeskriptorer:

ændring af eksisterende egenskaber via deskriptorer #

Hvis der allerede findes en egen ejendom, ændres egenskaben ved at definere den via en deskriptor. På den ene side, der giver os mulighed for at bruge Object.defineProperty() som opgave:

på den anden side kan vi også brugeObject.defineProperty() for at omdanne en dataegenskab til en getter (og omvendt):

faldgrube: arvelige skrivebeskyttede egenskaber kan ikke tildeles #

Hvis en arvelig egenskab er skrivebeskyttet, kan vi ikke bruge tildeling til at ændre den. Begrundelsen er, at tilsidesættelse af en arvelig ejendom ved at oprette en egen ejendom kan ses som ikke-destruktivt at ændre den arvede ejendom. Formentlig, hvis en ejendom er ikke-skrivbar, bør vi ikke kunne gøre det.

lad os se på et eksempel:

Vi kan ikke ændre egenskaben via tildeling. Men vi kan stadig oprette en egen ejendom ved at definere den:

Object.defineProperty(obj, 'prop', {value: 2});assert.equal(obj.prop, 2);

Accessoregenskaber, der ikke har en setter, betragtes også som skrivebeskyttede:

API: ejendomsdeskriptorer #

følgende funktioner giver dig mulighed for at arbejde med ejendomsdeskriptorer:

brug sager til objekt.Hent propertydescriptors () #

objekt.Hent propertydescriptors (): kopiering af egenskaber til et objekt #

siden ES6 har JavaScript allerede haft en værktøjsmetode til kopiering af egenskaber: Object.assign(). Denne metode bruger dog enkle get og set-operationer til at kopiere en ejendom, hvis nøgle er key:

target = source;

det betyder, at det kun opretter en trofast kopi af en ejendom, hvis:

  • dens attribut writable er true og dens attribut enumerable er true (fordi det er sådan, opgave opretter egenskaber).
  • det er en dataegenskab.

følgende eksempel illustrerer denne begrænsning. Objekt sourcehar en setter, hvis nøgle erdata.

Hvis vi bruger Object.assign() til kopiering af ejendom data, konverteres tilbehørsegenskaben data til en dataegenskab:

heldigvis bruger Object.getOwnPropertyDescriptors() sammen med Object.defineProperties() kopierer trofast ejendommen data:

faldgrube: kopieringsmetoder, der bruger super #

en metode, der bruger super er fast forbundet med sit hjemmeobjekt (det objekt, det er gemt i). Der er i øjeblikket ingen måde at kopiere eller flytte en sådan metode til et andet objekt.

objekt.Hent propertydescriptors (): kloning af objekter #

lav kloning ligner kopieringsegenskaber, hvorfor Object.getOwnPropertyDescriptors() også er et godt valg her.

for at oprette klonen bruger vi Object.create():

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.