È probabile che la maggior parte dell'interazione con le proprietà degli oggetti a livello di superficie, tra cui la creazione di valori letterali oggetto e l'impostazione e l'accesso utilizzando le chiavi. Tuttavia, puoi configurare internamente qualsiasi proprietà un oggetto per un controllo granulare sulla modalità di accesso a tali proprietà, modificati e definiti. Ogni proprietà di un oggetto ha un insieme di attributi invisibili contenente i metadati associati alla proprietà in questione, denominati "proprietà descrittori".
A ogni proprietà sono associati due tipi di descrittori: descrittori di dati e accessori. Un descrittore di dati include coppie chiave-valore che contengono il valore di una proprietà, indipendentemente dal fatto che è scrivibile, configurabile o enumerabile. I descrittori della funzione di accesso contengono funzioni che vengono eseguite quando si imposta, modifica o si accede a una proprietà.
Proprietà | Tipo di descrittore | Valore predefinito da Object. |
Descrizione |
---|---|---|---|
[[Value]] |
Dati | undefined |
Contiene il valore di una proprietà. |
[[Writable]] |
Dati | false |
Determina se puoi modificare il valore della proprietà. |
[[Get]] |
Funzione di accesso | undefined |
La funzione getter della proprietà, che viene eseguita quando accessibile la proprietà. |
[[Set]] |
Funzione di accesso | undefined |
La funzione setter della proprietà, che viene eseguita quando viene impostata o modificata. |
[[Configurable]] |
Entrambi | false |
Se questo è false , la proprietà non può essere eliminata e i relativi
non possono essere modificati. Se è false e
[[Writable]] è true , il valore della proprietà può
essere ancora modificate. |
[[Enumerable]] |
Entrambi | false |
Se si tratta di true , puoi eseguire l'iterazione della proprietà utilizzando
Loop for. o statica Object.
. |
Ognuna di queste proprietà utilizza la stessa forma abbreviata di [[Prototype]]
, per indicare
che non è possibile accedere direttamente a queste proprietà. Utilizza invece
Object.defineProperty()
metodo statico per definire o modificare le proprietà di un
. Object.defineProperty()
accetta tre argomenti: l'oggetto su cui agire,
la chiave di proprietà da creare o modificare e un oggetto contenente
descrittori associati alla proprietà che viene creata o modificata.
Per impostazione predefinita, le proprietà create utilizzando Object.defineProperty()
non sono scrivibili, enumerabili o configurabili. Tuttavia, qualsiasi proprietà che crei
come parte del valore letterale oggetto o utilizzando la notazione punto o parentesi
scrivibili, enumerabili e configurabili.
const myObj = {};
Object.defineProperty(myObj, 'myProperty', {
value: true,
writable: false
});
myObj.myProperty;
> true
myObj.myProperty = false;
myObj.myProperty;
> true
Ad esempio, quando [[Writable]]
ha un valore false
, stai tentando di impostare un nuovo valore
per la proprietà associata non riesce a controllare in modo silenzioso al di fuori della modalità con restrizioni e genera un
Errore in modalità massima:
{
const myObj = {};
Object.defineProperty(myObj, 'myProperty', {
value: true,
writable: false
});
myObj.myProperty = false;
myObj.myProperty;
}
> true
(function () {
"use strict";
const myObj = {};
Object.defineProperty(myObj, 'myProperty', {
value: true,
writable: false
});
myObj.myProperty = false;
myObj.myProperty;
}());\
> Uncaught TypeError: "myProperty" is read-only
Fare un uso efficace dei descrittori è un concetto abbastanza avanzato, ma
comprendere la struttura interna di un oggetto è essenziale per comprendere
le sintassi utilizzate nell'uso degli oggetti nei modi più comuni. Ad esempio:
quando si utilizza il metodo statico Object.create()
, questi concetti
che ti offre un controllo granulare su tutti i prototipi collegati al nuovo
.
Object.create()
crea un nuovo oggetto utilizzando un oggetto esistente come relativo
un prototipo di modello. In questo modo, il nuovo oggetto può ereditare proprietà e metodi da un altro
un oggetto definito dall'utente, come gli oggetti ereditano le proprietà
Prototipo Object
integrato di JavaScript. Quando richiami Object.create()
con
un oggetto come argomento, crea un oggetto vuoto con l'oggetto passato come
del suo prototipo.
const myCustomPrototype = {
'myInheritedProp': 10
};
const newObject = Object.create( myCustomPrototype );
newObject;
> Object { }
<prototype>: Object { myInheritedProp: 10 }
myInheritedProp: 10
<prototype>: Object { … }
Object.create
può prendere un secondo argomento che specifica le proprie proprietà per
appena creato utilizzando una sintassi simile a Object.defineProperty()
:
cioè un oggetto che mappa le chiavi a un insieme di attributi descrittori:
const myCustomPrototype = {
'myInheritedProp': 10
};
const myObj = Object.create( myCustomPrototype, {
myProperty: {
value: "The new property value.",
writable: true,
configurable: true
}
});
myObj;
> Object { … }
myProperty: "The new property value."
<prototype>: Object { myInheritedProp: 10 }
In questo esempio, il nuovo oggetto (myObj
) utilizza un valore letterale oggetto
(myCustomPrototype
) come prototipo, che a sua volta contiene i file
Object.prototype
, generando una serie di prototipi ereditati chiamati
prototipazione. Ogni oggetto ha un prototipo, assegnato o ereditato,
che ha un proprio prototipo assegnato o ereditato. Questa catena termina con
Prototipo di null
, che non dispone di un proprio prototipo.
const myPrototype = {
'protoProp': 10
};
const newObject = Object.setPrototypeOf( { 'objProp' : true }, myPrototype );
newObject;
> Object { objProp: true }
objProp: true
<prototype>: Object { protoProp: 10 }
protoProp: 10
<prototype>: Object { … }
Le proprietà contenute nel prototipo di un valore sono disponibili al "livello superiore" di un oggetto, senza dover accedere direttamente alla proprietà prototype:
const objectLiteral = {
"value" : true
};
objectLiteral;
> Object { value: true }
value: true
<prototype>: Object { … }
objectLiteral.toString();
"[object Object]"
Questo schema vale per l'intera catena di prototipi associata a un oggetto: quando tenta di accedere a una proprietà, l'interprete lo cerca proprietà in ogni "livello" della catena del prototipo, dall'alto verso il basso, finché trova la proprietà o termina la catena:
const myCustomPrototype = {
'protoProp': "Prototype property value."
};
const myObj = Object.create( myCustomPrototype, {
myProperty: {
value: "Top-level property value.",
writable: true,
configurable: true
}
});
myObj.protoProp;
> "Prototype property value."
Verifica le tue conoscenze
Quali descrittori sono le funzioni di accesso?
[[Set]]
[[Get]]
[[Writable]]