Maybaygiare.org

Blog Network

Atrybuty właściwości obiektu w JavaScript

w tym wpisie na blogu przyjrzymy się bliżej temu, jak specyfikacja ECMAScript widzi obiekty JavaScript. W szczególności właściwości nie są atomowe w spec, ale składają się z wielu atrybutów (pola myśli w rekordzie). Nawet wartość właściwości danych jest przechowywana w atrybucie!

spis treści:

struktura obiektów #

w specyfikacji ECMAScript obiekt składa się z:

  • wewnętrzne sloty, które są lokalizacjami pamięci, które nie są dostępne z JavaScript, tylko do operacji w specyfikacji.
  • zbiór właściwości. Każda właściwość kojarzy klucz z atrybutami (pomyśl pola w rekordzie).

wewnętrzne sloty #

oto jak specyfikacja opisuje wewnętrzne sloty (nacisk jest mój):

  • wewnętrzne sloty odpowiadają wewnętrznemu stanowi, który jest powiązany z obiektami i używany przez różne algorytmy specyfikacji ECMAScript.
  • wewnętrzne sloty nie są właściwościami obiektów i nie są dziedziczone.
  • w zależności od konkretnej specyfikacji gniazda wewnętrznego, taki stan może składać się z wartości:
    • dowolnego typu języka ECMAScript lub
    • określonych wartości typu specyfikacji ECMAScript.
  • o ile wyraźnie nie określono inaczej, wewnętrzne sloty są przydzielane jako część procesu tworzenia obiektu i nie mogą być dynamicznie dodawane do obiektu.
  • o ile nie określono inaczej, wartością początkową wewnętrznego gniazda jest wartośćundefined.
  • różne algorytmy w tej specyfikacji tworzą obiekty, które mają wewnętrzne sloty. Jednak język ECMAScript nie zapewnia bezpośredniego sposobu kojarzenia wewnętrznych szczelin z obiektem.
  • wewnętrzne metody i wewnętrzne sloty są identyfikowane w tej specyfikacji za pomocą nazw zamkniętych w podwójnych nawiasach kwadratowych].

istnieją dwa rodzaje gniazd wewnętrznych:

  • gniazda metod do manipulowania obiektami (uzyskiwanie właściwości, Ustawianie właściwości, itp.)
  • Data slots with storage (listed in the table below)
Internal data slot Type
] null | object
] boolean
] List of entries

Descriptions for these data sloty:

klucze właściwości #

kluczem właściwości jest:

  • ciąg znaków
  • symbol

atrybuty właściwości #

istnieją dwa rodzaje właściwości i mają różne atrybuty:

  • właściwość danych przechowuje dane. Jego atrybuty value posiadają dowolną wartość JavaScript.
  • właściwość accessor ma funkcję getter i / lub funkcję setter. Pierwsza z nich jest przechowywana w atrybucie get, druga w atrybucie set.

poniższa tabela zawiera listę wszystkich atrybutów właściwości.

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 określa, czy wartość właściwości danych może zostać zmieniona.
  • configurable określa, czy atrybuty właściwości mogą zostać zmienione. Jeśli jest tofalse, to:

    • nie można usunąć właściwości.
    • nie można zmienić właściwości z właściwości danych na właściwość accessora lub odwrotnie.
    • nie możesz zmienić żadnego atrybutu innego niżvalue.
    • dozwolona jest jednak jeszcze jedna zmiana atrybutów: Możesz zmienić writable z true na false. Uzasadnienie tej anomalii jest historyczne: właściwość.length tablic zawsze była zapisywalna i niemożliwa do skonfigurowania. Zezwolenie na zmianę atrybutuwritable umożliwia nam zamrożenie tablic.
  • enumerable wpływa na niektóre operacje (takie jakObject.assign()). Jeśli jest to false, wtedy te operacje ignorują właściwość.

deskryptory właściwości #

deskryptor właściwości koduje atrybuty właściwości jako obiekt JavaScript. Ich interfejsy maszynopisu wyglądają następująco.

znaki zapytania wskazują, że każda właściwość jest opcjonalna. Jeśli pominiesz właściwość podczas przekazywania deskryptora do operacji, zostanie użyta jej wartość domyślna.

pobieranie deskryptorów dla właściwości #

poniższy kod pobiera deskryptor obiektu dla właściwości danych first:

w następnym przykładzie pobieramy deskryptor właściwości dla gettera fullName:

używając desc()w linii A jest obejściem tak, że .deepEqual() działa.

tworzenie nowych właściwości za pomocą deskryptorów #

można również tworzyć nowe właściwości za pomocą deskryptorów właściwości:

zmiana istniejących właściwości za pomocą deskryptorów #

Jeśli własna właściwość już istnieje, wtedy zdefiniowanie jej za pomocą deskryptora zmienia tę właściwość. Z jednej strony, która pozwala nam użyćObject.defineProperty() jak przypisanie:

z drugiej strony, możemy również użyć Object.defineProperty(), aby zmienić właściwość danych w getter (i odwrotnie):

Pitfall: odziedziczone właściwości tylko do odczytu nie mogą być przypisane do #

Jeśli odziedziczona właściwość jest tylko do odczytu, nie możemy użyć przypisania do jej zmiany. Uzasadnieniem jest to, że nadpisanie odziedziczonej właściwości przez utworzenie własnej właściwości może być postrzegane jako nieniszcząca zmiana odziedziczonej właściwości. Prawdopodobnie, jeśli właściwość nie jest zapisywalna, nie powinniśmy być w stanie tego zrobić.

spójrzmy na przykład:

nie możemy zmienić właściwości poprzez przypisanie. Ale nadal możemy stworzyć własną właściwość, definiując ją:

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

właściwości Accessora, które nie mają settera, są również uważane za Tylko do odczytu:

API: property descriptors #

następujące funkcje umożliwiają pracę z deskryptorami właściwości:

przypadki użycia dla obiektu.getOwnPropertyDescriptors () #

obiekt.getOwnPropertyDescriptors (): kopiowanie właściwości do obiektu #

od ES6 JavaScript ma już narzędzie do kopiowania właściwości: Object.assign(). Jednak ta metoda wykorzystuje proste operacje get I set do skopiowania właściwości, której kluczem jest key:

target = source;

, co oznacza, że tworzy wierną kopię właściwości tylko wtedy, gdy:

  • jej atrybut writable to true I jego atrybutem enumerable jest true (ponieważ w ten sposób assignment tworzy właściwości).
  • jest to właściwość danych.

poniższy przykład ilustruje to ograniczenie. Obiekt source posiada seter, którego kluczem jest data.

jeśli użyjemy Object.assign() do skopiowania właściwości data, to właściwość accessor data zostanie przekonwertowana na właściwość danych:

na szczęście, używając Object.getOwnPropertyDescriptors() wraz z Object.defineProperties() wiernie kopiuje nieruchomość data:

: kopiowanie metod, które używają super #

metoda, która używa super jest mocno połączona ze swoim obiektem domowym (obiektem, w którym jest przechowywana). Obecnie nie ma możliwości skopiowania lub przeniesienia takiej metody do innego obiektu.

obiekt.getOwnPropertyDescriptors(): klonowanie obiektów #

płytkie klonowanie jest podobne do właściwości kopiowania, dlatego też Object.getOwnPropertyDescriptors() jest tu dobrym wyborem.

aby utworzyć klon, używamyObject.create():

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.