Maybaygiare.org

Blog Network

Atribute ale proprietăților obiectului în JavaScript

În acest post pe blog, vom lua o privire mai atentă la modul în care CAIETUL DE SARCINI ECMAScript vede obiecte JavaScript. În special, proprietățile nu sunt atomice în spec, dar compus din mai multe atribute (cred că câmpurile într-o înregistrare). Chiar și valoarea unei proprietăți de date este stocată într-un atribut!

cuprins:

structura obiectelor #

în specificația ECMAScript, un obiect este format din:

  • sloturi interne, care sunt locații de stocare care nu sunt accesibile din JavaScript, numai pentru operațiunile din caietul de sarcini.
  • o colecție de proprietăți. Fiecare proprietate asociază o cheie cu atribute (gândiți câmpurile dintr-o înregistrare).

sloturi interne #

acesta este modul în care specificația descrie sloturile interne (accentul este al meu):

  • sloturile interne corespund stării interne care este asociată cu obiecte și utilizată de diferiți algoritmi de specificație ECMAScript.
  • sloturile interne nu sunt proprietăți ale obiectelor și nu sunt moștenite.
  • în funcție de specificația slotului intern specific, o astfel de stare poate consta din valori:
    • de orice tip de limbaj ECMAScript sau
    • de valori specifice tipului de specificație ECMAScript.
  • dacă nu se specifică altfel în mod explicit, sloturile interne sunt alocate ca parte a procesului de creare a unui obiect și nu pot fi adăugate dinamic unui obiect.
  • dacă nu se specifică altfel, valoarea inițială a unui slot intern este valoareaundefined.
  • diferiți algoritmi din această specificație creează obiecte care au sloturi interne. Cu toate acestea, limbajul ECMAScript nu oferă nicio modalitate directă de a asocia sloturile interne cu un obiect.
  • metodele interne și sloturile interne sunt identificate în cadrul acestei specificații folosind nume incluse în paranteze pătrate duble].

există două tipuri de sloturi interne:

  • sloturi de metodă pentru manipularea obiectelor (obținerea proprietăților, setarea proprietăților etc.)
  • Data slots with storage (listed in the table below)
Internal data slot Type
] null | object
] boolean
] List of entries

Descriptions for these data sloturi:

chei de proprietate #

cheia unei proprietăți este fie:

  • un șir
  • un simbol

atribute de proprietate #

există două tipuri de proprietăți și au atribute diferite:

  • o proprietate de date stochează date. Atributele salevalue deține orice valoare JavaScript.
  • o proprietate accessor are o funcție getter și / sau o funcție setter. Primul este stocat în atributul get, acesta din urmă în atributul set.

următorul tabel listează toate atributele proprietății.

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 determină dacă valoarea unei proprietăți de date poate fi modificată.
  • configurable determină dacă atributele unei proprietăți pot fi modificate. Dacă este false, atunci:

    • nu puteți șterge proprietatea.
    • nu puteți schimba o proprietate dintr-o proprietate de date într-o proprietate accessor sau invers.
    • nu puteți modifica alt atribut decâtvalue.
    • Cu toate acestea, este permisă încă o modificare a atributului: Puteți schimbawritable de latrue lafalse. Motivul din spatele acestei anomalii este istoric: proprietatea .length a matricelor a fost întotdeauna scrisă și neconfigurabilă. Permiterea modificării atributului writable ne permite să înghețăm matricele.
  • enumerable influențează unele operații (cum ar fiObject.assign()). Dacă este false, atunci acele operațiuni ignoră proprietatea.

descriptori de proprietate #

un descriptor de proprietate codifică atributele unei proprietăți ca obiect JavaScript. Interfețele lor tipografice arată după cum urmează.

semnele de întrebare indică faptul că fiecare proprietate este opțională. Dacă omiteți o proprietate atunci când treceți un descriptor la o operație, atunci se utilizează valoarea implicită a acesteia.

regăsirea descriptorilor pentru proprietăți #

următorul cod preia descriptorul obiectului pentru proprietatea de date first:

în exemplul următor, vom prelua descriptor de proprietate pentru getter fullName:

folosind desc() în linia A este o lucrare în jurul, astfel încât .deepEqual() lucrări.

crearea de proprietăți noi prin descriptori #

de asemenea, puteți crea proprietăți noi prin descriptori de proprietăți:

schimbarea proprietăților existente prin descriptori #

dacă o proprietate proprie există deja, atunci definirea ei printr-un descriptor modifică acea proprietate. Pe de o parte, care ne permite să folosimObject.defineProperty() ca atribuire:

pe de altă parte, Putem folosi Object.defineProperty() pentru a transforma o proprietate de date într-un getter (și invers):

capcană: proprietățile moștenite numai în citire nu pot fi atribuite #

dacă o proprietate moștenită este numai în citire, atunci nu putem folosi atribuirea pentru a o schimba. Motivul este că suprascrierea unei proprietăți moștenite prin crearea unei proprietăți proprii poate fi văzută ca o schimbare nedistructivă a proprietății moștenite. Fără îndoială, dacă o proprietate nu poate fi scrisă, nu ar trebui să putem face asta.

să ne uităm la un exemplu:

Nu putem schimba proprietatea prin atribuire. Dar putem crea în continuare o proprietate proprie definind-o:

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

proprietățile accesoriilor care nu au un setter sunt, de asemenea, considerate a fi doar în citire:

API: descriptori de proprietate #

următoarele funcții vă permit să lucrați cu descriptori de proprietate:

utilizați cazuri pentru obiect.getOwnPropertyDescriptors () #

obiect.getOwnPropertyDescriptors (): copierea proprietăților într-un obiect #

de la ES6, JavaScript are deja o metodă de instrument pentru copierea proprietăților: Object.assign(). Cu toate acestea, această metodă utilizează operații simple get și set pentru a copia o proprietate a cărei cheie este key:

target = source;

asta înseamnă că creează doar o copie fidelă a unei proprietăți dacă:

  • atributul său writable este true și atributul său enumerable este true (pentru că așa atribuirea creează proprietăți).
  • este o proprietate de date.

următorul exemplu ilustrează această limitare. Obiectul source are un setter a cărui cheie este data.

dacă folosim Object.assign() pentru a copia proprietatea data, atunci proprietatea Accesor data este convertită într-o proprietate de date:

Din fericire, folosind Object.getOwnPropertyDescriptors() împreună cu Object.defineProperties() copiază fidel proprietatea data:

capcană: copierea metodelor care utilizeazăsuper #

o metodă care utilizeazăsuper este strâns legată de obiectul său de origine (obiectul în care este stocat). În prezent, nu există nicio modalitate de a copia sau muta o astfel de metodă într-un alt obiect.

obiect.getOwnPropertyDescriptors (): clonarea obiectelor #

clonarea superficială este similară cu proprietățile de copiere, motiv pentru care Object.getOwnPropertyDescriptors() este o alegere bună și aici.

pentru a crea clona, folosim Object.create():

Lasă un răspuns

Adresa ta de email nu va fi publicată.