Maybaygiare.org

Blog Network

Attribut för objektegenskaper i JavaScript

i det här blogginlägget tittar vi närmare på hur ECMAScript-specifikationen ser JavaScript-objekt. I synnerhet är egenskaper inte atomära i specifikationen, men består av flera attribut (tänk fält i en post). Även värdet på en dataegenskap lagras i ett attribut!

Innehållsförteckning:

strukturen för objekt #

i ECMAScript-specifikationen består ett objekt av:

  • interna platser, som är lagringsplatser som inte är tillgängliga från JavaScript, endast för operationer i specifikationen.
  • en samling egenskaper. Varje egenskap associerar en nyckel med attribut (tänk fält i en post).

interna slitsar #

Så här beskriver specifikationen interna slitsar (betoningen är min):

  • interna slitsar motsvarar internt tillstånd som är associerat med objekt och används av olika ECMAScript-specifikationsalgoritmer.
  • interna slitsar är inte objektegenskaper och de är inte ärvda.
  • beroende på den specifika interna spårspecifikationen kan ett sådant tillstånd bestå av värden:
    • av vilken ECMAScript-språktyp som helst eller
    • av specifika ECMAScript-specifikationstypvärden.
  • Om inte annat uttryckligen anges tilldelas interna slitsar som en del av processen att skapa ett objekt och får inte läggas dynamiskt till ett objekt.
  • Om inget annat anges är initialvärdet för en intern lucka värdetundefined.
  • olika algoritmer inom denna specifikation skapar objekt som har interna slitsar. ECMAScript-språket ger emellertid inget direkt sätt att associera interna slitsar med ett objekt.
  • interna metoder och interna slitsar identifieras inom denna specifikation med hjälp av namn som är inneslutna i dubbla hakparenteser ].

det finns två typer av interna slitsar:

  • Metodspår för att manipulera objekt (få egenskaper, inställningsegenskaper 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:

Egenskapsnycklar #

nyckeln till en egenskap är antingen:

  • en sträng
  • en symbol

Egenskapsattribut #

det finns två typer av egenskaper och de har olika attribut:

  • en datafastighet lagrar data. Dess attribut value har något JavaScript-värde.
  • en accessor-egenskap har en getter-funktion och / eller en setter-funktion. Den förra lagras i attributet get, den senare i attributet set.

i följande tabell visas alla egenskapsattribut.

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 bestämmer om värdet på en dataegenskap kan ändras.
  • configurable bestämmer om attributen för en egenskap kan ändras. Om det är false, då:
    • Du kan inte ta bort egenskapen.
    • Du kan inte ändra en egenskap från en dataegenskap till en accessor-egenskap eller vice versa.
    • Du kan inte ändra något annat attribut än value.
    • men ytterligare en attributändring är tillåten: Du kan ändra writable från true till false. Motiveringen bakom denna anomali är Historisk: egenskapen .length av arrayer har alltid varit skrivbar och icke-konfigurerbar. Genom att låta attributet writable ändras kan vi frysa matriser.
  • enumerable påverkar vissa operationer (t.ex.Object.assign()). Om det är false, ignorerar dessa operationer egenskapen.

egenskapsbeskrivningar #

en egenskapsbeskrivare kodar attributen för en egenskap som ett JavaScript-objekt. Deras TypeScript-gränssnitt ser ut som följer.

frågetecknen indikerar att varje egenskap är valfri. Om du utelämnar en egenskap när du skickar en deskriptor till en operation används dess standardvärde.

hämta deskriptorer för egenskaper #

följande kod hämtar objektbeskrivaren för dataegenskapen first:

i nästa exempel hämtar vi egenskapsbeskrivaren för gettern fullName:

med desc() I rad A är ett arbete så att .deepEqual() fungerar.

skapa nya egenskaper via deskriptorer #

Du kan också skapa nya egenskaper via egenskapsdeskriptorer:

ändra befintliga egenskaper via deskriptorer #

om en egen egenskap redan finns, ändrar den egenskapen genom att definiera den via en deskriptor. Å ena sidan som tillåter oss att använda Object.defineProperty() liknande uppdrag:

å andra sidan kan vi också använda Object.defineProperty() för att förvandla en dataegenskap till en getter (och vice versa):

fallgrop: ärvda skrivskyddade egenskaper kan inte tilldelas #

om en ärvd egenskap är skrivskyddad kan vi inte använda tilldelning för att ändra den. Motivet är att åsidosätta en ärvd egendom genom att skapa en egen egendom kan ses som icke-destruktivt ändra den ärvda egendomen. Förmodligen, om en fastighet inte är skrivbar, borde vi inte kunna göra det.

låt oss titta på ett exempel:

Vi kan inte ändra egenskapen via tilldelning. Men vi kan fortfarande skapa en egen egenskap genom att definiera den:

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

Accessoregenskaper som inte har en setter anses också vara skrivskyddade:

API: egenskapsbeskrivningar #

följande funktioner låter dig arbeta med egenskapsbeskrivningar:

använd fall för objekt.Getownpropertydescriptors () #

objekt.getOwnPropertyDescriptors (): Kopiera egenskaper till ett objekt #

sedan ES6 har JavaScript redan haft en verktygsmetod för kopiering av egenskaper: Object.assign(). Denna metod använder emellertid enkla get-och set-operationer för att kopiera en egenskap vars nyckel är key:

target = source;

det betyder att det bara skapar en trogen kopia av en egenskap om:

  • dess attribut writable är true och dess attribut enumerable är true (eftersom det är så tilldelning skapar egenskaper).
  • Det är en dataegenskap.

följande exempel illustrerar denna begränsning. Object sourcehar en setter vars nyckel är data.

om vi använder Object.assign() för att kopiera egendom data, konverteras accessor-egenskapen data till en dataegenskap:

lyckligtvis använder du Object.getOwnPropertyDescriptors() tillsammans med Object.defineProperties() kopierar troget egenskapen data:

fallgrop: kopieringsmetoder som använder super #

en metod som använder super är ordentligt ansluten till sitt hemobjekt (objektet det lagras i). Det finns för närvarande inget sätt att kopiera eller flytta en sådan metod till ett annat objekt.

objekt.getownpropertydescriptors (): kloning objekt #

Grunt kloning liknar kopieringsegenskaper, varför Object.getOwnPropertyDescriptors() är ett bra val här också.

för att skapa klonen använder vi Object.create():

Lämna ett svar

Din e-postadress kommer inte publiceras.