[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty [Back]  [Original]

Object.defineProperty() - JavaScript | MDN

Cette page a t traduite partir de l'anglais par la communaut. Vous pouvez contribuer en rejoignant la communaut francophone sur MDN Web Docs.

View in English Always switch to English

Object.defineProperty()

Baseline Large disponibilit

Cette fonctionnalit est bien tablie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.

La mthode statique Object.defineProperty() permet de dfinir une nouvelle proprit ou de modifier une proprit existante, directement sur un objet. La mthode renvoie l'objet modifi.

Note : Cette mthode est directement appele via le constructeur Object plutt que sur les instances de type Object.

Dans cet article

Exemple interactif

const object1 = {};

Object.defineProperty(object1, "property1", {
  value: 42,
  writable: false,
});

object1.property1 = 77;
// Throws an error in strict mode

console.log(object1.property1);
// Expected output: 42

Syntaxe

js
Object.defineProperty(obj, prop, descripteur);

Paramtres

obj

L'objet sur lequel on souhaite dfinir ou modifier une proprit.

prop

Le nom ou le symbole (Symbol) de la proprit qu'on dfinit ou qu'on modifie.

descripteur

Le descripteur de la proprit qu'on dfinit ou qu'on modifie.

Valeur de retour

L'objet qui a t pass la fonction et qui a ventuellement t modifi.

Description

Cette mthode permet d'ajouter ou de modifier une proprit d'un objet avec une certaine prcision. En effet, quand on ajoute une proprit normalement (via une affectation), on cre une proprit dont le comportement par dfaut fait qu'elle sera liste dans une numration de proprits (par exemple avec une boucle for...in ou via la mthode Object.keys), dont la valeur peut tre change et qui peut tre supprime via delete. La mthode Object.defineProperty() permet de prciser le comportement attendu, potentiellement diffrent de celui par dfaut.

Les descripteurs de proprit existent en deux versions : les descripteurs de donnes et les descripteurs d'accesseur. Un descripteur de donnes est une proprit qui possde une valeur et qui peut ou non tre accessible en criture. Un descripteur d'accesseur est une proprit dcrite par une paire d'accesseur/mutateur (getter/setter) qui sont des fonctions. Un descripteur est un descripteur de donnes ou un descripteur d'accesseur, il ne peut pas tre les deux.

Les descripteurs de donnes et d'accesseur sont des objets. Ils partagent les proprits suivantes (la valeur par dfaut indique est utilise lorsqu'on passe par Object.defineProperty()) :

configurable

true si et seulement si le type de ce descripteur de proprit peut tre chang et si la proprit peut/pourra tre supprime de l'objet correspondant.. La valeur par dfaut est false.

enumerable

true si et seulement si la proprit apparat lors de l'numration des proprits de l'objet correspondant. La valeur par dfaut est false.

Un descripteur de donnes possde les proprits optionnelles suivantes :

value

La valeur associe la proprit. Peut tre n'importe quelle valeur JavaScript valide (un nombre, un objet, etc.). La valeur par dfaut est undefined.

writable

true si et seulement si la valeur associe la proprit peut tre modifie en utilisant un oprateur d'affectation. La valeur par dfaut est false.

Un descripteur d'accesseur possde les proprits optionnelles suivantes :

get

Une fonction qui est utilise comme accesseur (getter) pour la proprit ou bien undefined s'il n'existe pas d'accesseur. La valeur de retour de la fonction sera utilise comme valeur pour la proprit. Lorsqu'on accde la proprit, la fonction est appele sans argument avec this qui est l'objet pour lequel on souhaite consulter la proprit. La valeur par dfaut est undefined.

set

Une fonction qui est utilise comme mutateur (setter) pour la proprit ou bien undefined s'il n'existe pas de mutateur. Pour unique argument, la fonction recevra la nouvelle valeur affecter la proprit. Le contexte this pass est l'objet sur lequel on souhaite modifier la proprit. La valeur par dfaut est undefined.

Si un descripteur ne possde aucune des cls value, writable, get ou set, il est considr comme un descripteur de donnes. Si un descripteur possde la fois une proprit value ou writable et une proprit get ou set, un exception sera dclenche.

Il faut garder l'esprit que ces options ne sont pas ncessairement les descripteurs des proprits propres. Elles peuvent tre hrites et faire partie de la chaine des prototypes. Afin de s'assurer que les valeur par dfaut sont prserves, on peut d'abord geler le prototype Object, dfinir toutes les options explicitement ou faire pointer la proprit Object.prototype.__proto__ vers null (par exemple avec Object.create(null)).

js
var obj = {};
// en utilisant __proto__
Object.defineProperty(obj, "cl", {
  __proto__: null, // aucune proprit hrite
  value: "static", // non numrable
  // non configurable
  // non accessible en criture
  // par dfaut
});

// en tant explicite
Object.defineProperty(obj, "cl", {
  enumerable: false,
  configurable: false,
  writable: false,
  value: "static",
});

// en recyclant un objet
function avecValeur(valeur) {
  var d =
    avecValeur.d ||
    (avecValeur.d = {
      enumerable: false,
      writable: false,
      configurable: false,
      value: null,
    });
  if (d.value !== valeur) {
    d.value = valeur;
  }
  return d;
}
// ... autres instructions... puis
Object.defineProperty(obj, "cl", avecValeur("static"));

// si la mthode freeze est disponible,
// on peut empcher que du code ajoute des
// proprits (valeur, get, set, enumerable,
// writable, configurable) au prototype d'Object
(Object.freeze || Object)(Object.prototype);

Exemples

Pour plus d'exemples utilisant la mthode Object.defineProperty avec une syntaxe de masque binaire, voir les exemples supplmentaires.

Crer une proprit

Lorsqu'une proprit n'existe pas pour l'objet, Object.defineProperty() crera une nouvelle proprit telle qu'elle est dcrite. Certains champs du descripteur peuvent manquer, les valeurs par dfaut seront alors utilises. Tous les boolens ont false pour valeur par dfaut. Une proprit dfinie sans get/set/value/writable est appele gnrique et correspond un descripteur de donnes.

js
var o = {}; // on cre un nouvel objet

// Exemple d'une proprit ajoute via defineProperty
// avec un descripteur de donnes
Object.defineProperty(o, "a", {
  value: 37,
  writable: true,
  enumerable: true,
  configurable: true,
});
// la proprit 'a' existe pour l'objet o et vaut 37

// Exemple d'une proprit ajoute via defineProperty
// avec un descripteur d'accesseur
var valeurB = 38;
Object.defineProperty(o, "b", {
  get: function () {
    return valeurB;
  },
  set: function (nouvelleValeur) {
    valeurB = nouvelleValeur;
  },
  enumerable: true,
  configurable: true,
});
o.b; // 38
// la proprit 'b' existe pour l'objet o
// et vaut 38
// La valeur de o.b est dsormais toujours
// identique  valeurB, sauf si o.b est redfini

// On ne peut pas mlanger les deux :
Object.defineProperty(o, "conflit", {
  value: 0x9f91102,
  get: function () {
    return 0xdeadbeef;
  },
});
// une exception TypeError sera lance : value n'apparat
// que dans les descripteurs de donnes
// get n'apparait que dans les descripteurs d'accesseur

Modifier une proprit existante

Quand une proprit existe d'ores et dj pour un objet, Object.defineProperty() tentera de modifier la proprit pour qu'elle corresponde aux valeurs indiques dans le descripteur et la configuration de l'objet courant. Si l'ancien descripteur avait configurable false (la proprit est dite non-configurable), aucun attribut, l'exception de writable, ne peut tre chang. Dans ce cas, il n'est pas possible de changer entre les types de descripteur.

Si une proprit est non-configurable, son attribut writable ne peut tre mis qu' false.

Une exception TypeError peut tre leve quand on essaie de modifier des attributs de proprit non-configurables (en dehors des attributs value et writable) sauf dans le cas o les valeurs souhaites sont les mmes que les valeurs courantes.

Attribut writable

Lorsque l'attribut writable vaut false pour la proprit, cette dernire n'est plus accessible en criture. Il est impossible de la raffecter.

js
var o = {}; // On cre un nouvel objet

Object.defineProperty(o, "a", { value: 37, writable: false });

console.log(o.a); // inscrit 37 dans les journaux (logs)
o.a = 25; // Aucune exception n'est lance (on aurait une
// exception en mode strict, y compris si la
// valeur souhaite avait t la mme)
console.log(o.a); // inscrit toujours 37.
//L'affectation n'a pas fonctionn.
js
// En mode strict
(function () {
  "use strict";
  var o = {};
  Object.defineProperty(o, "b", {
    value: 2,
    writable: false,
  });
  o.b = 3; // dclenche une TypeError: "b" est en lecture seule
  return o.b; // renvoie 2 sans la ligne prcdente
})();

Comme on l'a vu dans l'exemple, essayer de modifier une proprit non accessible en criture ne la modifie pas. Cela ne rend pas d'erreur non plus (en mode non-strict).

Attribut enumerable

L'attribut de proprit enumerable permet de dfinir si la proprit est slectionne par Object.assign() ou via l'oprateur de dcomposition (spread). Pour les proprits qui ne sont pas nommes avec des symboles, les proprits numrables correspondent aux proprits qui sont listes avec une boucle for...in ou avec la mthode Object.keys().

js
var o = {};
Object.defineProperty(o, "a", {
  value: 1,
  enumerable: true,
});
Object.defineProperty(o, "b", {
  value: 2,
  enumerable: false,
});
Object.defineProperty(o, "c", {
  value: 3,
}); // enumerable vaut false par dfaut
o.d = 4; // enumerable vaut true par dfaut
// lorsqu'on cre une proprit
// en la dfinissant
Object.defineProperty(o, Symbol.for("e"), {
  value: 5,
  enumerable: true,
});
Object.defineProperty(o, Symbol.for("f"), {
  value: 6,
  enumerable: false,
});

for (var i in o) {
  console.log(i);
}
// affiche 'a' et 'd' (dans un ordre indfini)

Object.keys(o); // ['a', 'd']

o.propertyIsEnumerable("a"); // true
o.propertyIsEnumerable("b"); // false
o.propertyIsEnumerable("c"); // false
o.propertyIsEnumerable("d"); // true
o.propertyIsEnumerable(Symbol.for("e")); // true
o.propertyIsEnumerable(Symbol.for("f")); // false

var p = { ...o };
p.a; // 1
p.b; // undefined
p.c; // undefined
p.d; // 4
p[Symbol.for("e")]; // 5
p[Symbol.for("f")]; // undefined

Attribut configurable

L'attribut configurable permet de contrler si la proprit peut tre supprime et si les autres attributs de proprit (voir ci-avant), l'exception de value ou de writable, peuvent tre modifis.

js
var o = {};
Object.defineProperty(o, "a", {
  get: function () {
    return 1;
  },
  configurable: false,
});

Object.defineProperty(o, "a", { configurable: true });
// renvoie une TypeError

Object.defineProperty(o, "a", { enumerable: true });
// renvoie une TypeError

Object.defineProperty(o, "a", { set: function () {} });
// renvoie une TypeError (set tait non dfini avant)

Object.defineProperty(o, "a", {
  get: function () {
    return 1;
  },
});
// renvoie une TypeError
// (bien que le nouveau get soit identique au prcdent)

Object.defineProperty(o, "a", { value: 12 });
// renvoie une TypeError

console.log(o.a); // log 1
delete o.a; // Rien ne se passe
console.log(o.a); // log 1

Si l'attribut configurable de o.a avait t true, aucune de ces erreurs n'aurait t renvoye et la proprit aurait t supprime au final.

Ajouter des proprits et des valeurs par dfaut

Il est toujours important de savoir comment les valeurs par dfaut sont appliques. Le comportement est souvent diffrent entre une affectation simple et l'utilisation de Object.defineProperty(). Par exemple :

js
var o = {};

o.a = 1;
// est quivalent  :
Object.defineProperty(o, "a", {
  value: 1,
  writable: true,
  configurable: true,
  enumerable: true,
});

// D'un autre ct,
Object.defineProperty(o, "a", { value: 1 });
// sera quivalent  :
Object.defineProperty(o, "a", {
  value: 1,
  writable: false,
  configurable: false,
  enumerable: false,
});

Accesseurs et mutateurs adapts

L'exemple ci-dessous illustre comment implmenter un objet qui archive des donnes. Lorsque la proprit temprature est dfinie, on ajoute une entre au tableau archive :

js
function Archiviste() {
  var temprature = null;
  var archive = [];

  Object.defineProperty(this, "temprature", {
    get: function () {
      console.log("accs !");
      return temprature;
    },
    set: function (value) {
      temprature = value;
      archive.push({ val: temprature });
    },
  });

  this.getArchive = function () {
    return archive;
  };
}

var arc = new Archiviste();
arc.temprature; // "accs !"
arc.temprature = 11;
arc.temprature = 13;
arc.getArchive(); // [{val: 11}, {val: 13}]

Spcifications

Spcification
ECMAScript 2027 LanguageSpecification
# sec-object.defineproperty

Compatibilit des navigateurs

Voir aussi


Web Proxy Viewer  |  New URL  |  Original Page