Maybaygiare.org

Blog Network

Attributi delle proprietà dell’oggetto in JavaScript

In questo post del blog, diamo un’occhiata più da vicino a come le specifiche ECMAScript vedono gli oggetti JavaScript. In particolare, le proprietà non sono atomiche nelle specifiche, ma composte da più attributi (si pensi ai campi in un record). Anche il valore di una proprietà dati viene memorizzato in un attributo!

Sommario:

La struttura degli oggetti #

Nella specifica ECMAScript, un oggetto è costituito da:

  • Slot interni, che sono posizioni di archiviazione non accessibili da JavaScript, solo per le operazioni nella specifica.
  • Una raccolta di proprietà. Ogni proprietà associa una chiave con attributi (si pensi campi in un record).

Slot interni #

Questo è il modo in cui la specifica descrive gli slot interni (l’enfasi è mia):

  • Gli slot interni corrispondono allo stato interno associato agli oggetti e utilizzato da vari algoritmi di specifica ECMAScript.
  • Gli slot interni non sono proprietà dell’oggetto e non sono ereditati.
  • A seconda della specifica specifica dello slot interno, tale stato può essere costituito da valori:
    • di qualsiasi tipo di linguaggio ECMAScript o
    • di specifici valori del tipo di specifica ECMAScript.
  • Se non diversamente specificato, gli slot interni sono allocati come parte del processo di creazione di un oggetto e non possono essere aggiunti dinamicamente a un oggetto.
  • Se non diversamente specificato, il valore iniziale di uno slot interno è il valoreundefined.
  • Vari algoritmi all’interno di questa specifica creano oggetti con slot interni. Tuttavia, il linguaggio ECMAScript non fornisce alcun modo diretto per associare gli slot interni a un oggetto.
  • I metodi interni e gli slot interni sono identificati all’interno di questa specifica utilizzando nomi racchiusi tra doppie parentesi quadre].

Esistono due tipi di slot interni:

  • Slot di metodo per manipolare oggetti (ottenere proprietà, impostare proprietà, ecc.)
  • Data slots with storage (listed in the table below)
Internal data slot Type
] null | object
] boolean
] List of entries

Descriptions for these data slot:

Proprietà tasti #

La chiave di una proprietà è:

  • stringa
  • simbolo

gli attributi di Proprietà #

Ci sono due tipi di proprietà e hanno diversi attributi:

  • Una proprietà di dati memorizza i dati. I suoi attributivalue contengono qualsiasi valore JavaScript.
  • Una proprietà accessor ha una funzione getter e / o una funzione setter. Il primo è memorizzato nell’attributo get, il secondo nell’attributo set.

La seguente tabella elenca tutti gli attributi delle proprietà.

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 determina se è possibile modificare il valore di una proprietà dati.
  • configurable determina se gli attributi di una proprietà possono essere modificati. Se si tratta di false, allora:

    • Non è possibile eliminare la proprietà.
    • Non è possibile modificare una proprietà da una proprietà data a una proprietà accessor o viceversa.
    • Non è possibile modificare alcun attributo diverso da value.
    • Tuttavia, è consentita un’altra modifica di attributo: È possibile modificare writableda truea false. La logica alla base di questa anomalia è storica: la proprietà .length degli array è sempre stata scrivibile e non configurabile. Permettendo la suawritable attributo da modificare ci permette di congelare array.
  • enumerable influenza alcune operazioni (ad esempioObject.assign()). Se si tratta di false, tali operazioni ignorano la proprietà.

Descrittori di proprietà #

Un descrittore di proprietà codifica gli attributi di una proprietà come oggetto JavaScript. Le loro interfacce dattiloscritte sono le seguenti.

I punti interrogativi indicano che ogni proprietà è facoltativa. Se si omette una proprietà quando si passa un descrittore a un’operazione, viene utilizzato il suo valore predefinito.

Recupero dei descrittori per le proprietà #

Il codice seguente recupera il descrittore dell’oggetto per la proprietà dei dati first:

Nel prossimo esempio, recuperiamo il descrittore di proprietà per il getter fullName:

Usando desc()nella riga A è un work-around in modo che .deepEqual() funzioni.

Creazione di nuove proprietà tramite descrittori #

È anche possibile creare nuove proprietà tramite descrittori di proprietà:

Modifica delle proprietà esistenti tramite descrittori #

Se esiste già una proprietà propria, la definizione tramite un descrittore modifica tale proprietà. Da un lato che ci permette di usareObject.defineProperty() come assegnazione:

D’altra parte, possiamo anche usare Object.defineProperty() per trasformare una proprietà data in un getter (e viceversa):

Pitfall: le proprietà ereditate di sola lettura non possono essere assegnate a #

Se una proprietà ereditata è di sola lettura, allora non possiamo usare l’assegnazione per cambiarla. La logica è che l’override di una proprietà ereditata creando una proprietà propria può essere vista come una modifica non distruttiva della proprietà ereditata. Probabilmente, se una proprietà non è scrivibile, non dovremmo essere in grado di farlo.

Diamo un’occhiata a un esempio:

Non possiamo modificare la proprietà tramite assegnazione. Ma possiamo ancora creare una proprietà definendola:

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

Anche le proprietà di accesso che non hanno un setter sono considerate di sola lettura:

API: property descriptors #

Le seguenti funzioni consentono di lavorare con i descrittori di proprietà:

Use case for Object.getOwnPropertyDescriptors () #

Oggetto.getOwnPropertyDescriptors (): copiare le proprietà in un oggetto #

Da ES6, JavaScript ha già un metodo tool per copiare le proprietà:Object.assign(). Tuttavia, questo metodo utilizza semplice ottenere e impostare le operazioni di copia di un immobile la cui chiave è key:

target = source;

il che significa Che non solo crea una copia fedele di un immobile se:

  • l’attributo writabletrue e l’attributo di enumerabletrue (perché è così che l’assegnazione crea le proprietà).
  • Si tratta di una proprietà di dati.

Il seguente esempio illustra questa limitazione. Object sourceha un setter la cui chiave èdata.

Se si usa Object.assign() per copiare la struttura data, quindi la funzione di accesso di proprietà data viene convertito in una proprietà di dati:

Fortunatamente, utilizzando Object.getOwnPropertyDescriptors() con Object.defineProperties() non fedelmente copia la proprietà data:

Insidia: metodi di copia che utilizzano super #

Un metodo che utilizzasuper è saldamente connesso con il suo oggetto home (l’oggetto in cui è memorizzato). Al momento non è possibile copiare o spostare tale metodo su un oggetto diverso.

Oggetto.getOwnPropertyDescriptors (): clonazione di oggetti #

La clonazione superficiale è simile alle proprietà di copia, motivo per cuiObject.getOwnPropertyDescriptors() è una buona scelta anche qui.

Per creare il clone, usiamo Object.create():

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.