La majeure partie de votre interaction avec les propriétés des objets y compris la création de littéraux d'objets, la définition à l'aide de clés. Cependant, vous pouvez configurer en interne n'importe quelle propriété de un objet pour contrôler précisément l'accès à ces propriétés, modifiées et définies. Chaque propriété d'objet possède un ensemble d'attributs invisibles contenant les métadonnées associées à cette propriété, appelée "propriété de description. »
Deux types de descripteurs sont associés à chaque propriété: descripteurs de données et descripteurs d'accès. Un descripteur de données comprend des paires clé/valeur contenant la valeur d'une propriété, que cette propriété la valeur est accessible en écriture, configurable ou énumérable. Les descripteurs d'accesseur contiennent fonctions qui s'exécutent lorsqu'une propriété est définie, modifiée ou consultée.
Propriété | Type de descripteur | Valeur par défaut de Object.defineProperty() |
Description |
---|---|---|---|
[[Value]] |
Données | undefined |
Contient la valeur d'une propriété. |
[[Writable]] |
Données | false |
Détermine si vous pouvez modifier la valeur de la propriété. |
[[Get]] |
Accesseur | undefined |
La fonction getter de la propriété, qui s'exécute lorsque la est accessible. |
[[Set]] |
Accesseur | undefined |
La fonction setter de la propriété, qui s'exécute lorsque la propriété est définie ou modifiée. |
[[Configurable]] |
Les deux | false |
Si la valeur est false , la propriété ne peut pas être supprimée et ses
ne peuvent pas être modifiés. S'il s'agit de false et
[[Writable]] est true , la valeur de la propriété peut
restent inchangées. |
[[Enumerable]] |
Les deux | false |
Si la valeur est true , vous pouvez itérer la propriété en utilisant
Boucles for...in ou Object.keys() statique
. |
Chacune de ces propriétés utilise le même raccourci que [[Prototype]]
, ce qui indique
que ces propriétés ne sont pas destinées
à être accessibles directement. Utilisez plutôt la méthode
Object.defineProperty()
pour définir ou modifier les propriétés d'une
. Object.defineProperty()
accepte trois arguments: l'objet sur lequel agir,
la clé de la propriété à créer ou à modifier, ainsi qu'un objet contenant la
descripteurs associés à la propriété en cours de création ou de modification.
Par défaut, les propriétés créées avec Object.defineProperty()
ne sont ni accessibles en écriture, ni énumération, ni configurables. Cependant, toute propriété que vous créez
soit dans le littéral d'objet, soit en utilisant la notation par points ou accolades,
accessible en écriture, énumérable et configurable.
const myObj = {};
Object.defineProperty(myObj, 'myProperty', {
value: true,
writable: false
});
myObj.myProperty;
> true
myObj.myProperty = false;
myObj.myProperty;
> true
Par exemple, lorsque [[Writable]]
a une valeur false
, essayer de définir une nouvelle valeur
pour la propriété associée échoue silencieusement en dehors du mode strict et génère une
erreur en mode strict:
{
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
L'utilisation efficace des descripteurs
est un concept assez avancé, mais
comprendre la structure interne
d’un objet est essentiel pour comprendre
les syntaxes impliquées dans l’utilisation
d’objets de manière plus courante. Par exemple :
ces concepts entrent en jeu lorsque vous utilisez la méthode statique Object.create()
,
ce qui vous permet de contrôler précisément les prototypes attachés au nouveau
.
Object.create()
crée un objet en utilisant un objet existant comme son
un prototype. Cela permet au nouvel objet d'hériter des propriétés et méthodes d'un autre
défini par l'utilisateur de la même manière que les objets héritent des propriétés
Prototype Object
intégré de JavaScript. Lorsque vous appelez Object.create()
avec
un objet en tant qu'argument, un objet vide est créé, l'objet transmis étant
son prototype.
const myCustomPrototype = {
'myInheritedProp': 10
};
const newObject = Object.create( myCustomPrototype );
newObject;
> Object { }
<prototype>: Object { myInheritedProp: 10 }
myInheritedProp: 10
<prototype>: Object { … }
Object.create
peut utiliser un second argument spécifiant ses propres propriétés pour la fonction
objet que vous venez de créer à l'aide d'une syntaxe semblable à Object.defineProperty()
,
Autrement dit, un objet mappant des clés à un ensemble d'attributs de descripteurs:
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 }
Dans cet exemple, le nouvel objet (myObj
) utilise un littéral d'objet
(myCustomPrototype
) comme prototype, qui contient elle-même les données héritées
Object.prototype
. Il en résulte une série de prototypes hérités, appelés les
chaîne de prototypes. Chaque objet possède un prototype, qu'il soit attribué ou hérité,
qui possède son propre prototype attribué
ou hérité. Cette chaîne se termine à un
null
, qui n'a pas de prototype qui lui est propre.
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 { … }
Les propriétés contenues dans le prototype d'une valeur sont disponibles au "niveau supérieur" d'un objet, sans avoir à accéder directement à la propriété du prototype:
const objectLiteral = {
"value" : true
};
objectLiteral;
> Object { value: true }
value: true
<prototype>: Object { … }
objectLiteral.toString();
"[object Object]"
Ce modèle est valable pour l'ensemble de la chaîne de prototypes associée à objet: lorsqu'il tente d'accéder à une propriété, l'interprète la recherche. propriété à chaque "niveau" de la chaîne prototype, de haut en bas, jusqu'à ce qu'elle trouve la propriété ou la fin de la chaîne:
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."
Testez vos connaissances
Quels descripteurs sont des accesseurs ?
[[Get]]
[[Set]]
[[Writable]]