Cette page a été traduite à partir de l'anglais par la communauté.Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.
Object.freeze()
Baseline Widely available
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 méthodeObject.freeze() permet de geler un objet, c'est-à-dire qu'on empêche d'ajouter de nouvelles propriétés, de supprimer ou d'éditer des propriétés existantes, y compris en ce qui concerne leur caractère énumérable, configurable ou pour l'accès en écriture. L'objet devient ainsi immuable. La méthode renvoie l'objet ainsi « gelé ».
Dans cet article
Exemple interactif
const obj = { prop: 42,};Object.freeze(obj);obj.prop = 33;// Throws an error in strict modeconsole.log(obj.prop);// Expected output: 42Syntaxe
Object.freeze(obj);Paramètres
objL'objet à geler.
Valeur de retour
L'objet qui a été passé à la fonction.
Description
Rien ne pourra être ajouté ou supprimé dans l'ensemble des propriétés de l'objet gelé. Toute tentative échouera, silencieusement ou via une exceptionTypeError (la plupart du temps enmode strict).
Les propriétés qui sont des données ne pourront pas être changées et les attributswritable etconfigurable vaudrontfalse. Les propriétés qui sont des accesseurs ou des mutateurs fonctionneront de la même façon (et ne changeront pas la valeur associée malgré le fait qu'il n'y ait pas d'erreur). Les propriétés dont les valeurs sont des objets pourront être modifiées si ces objets ne sont pas gelés. Les tableaux peuvent également être gelés ce qui empêche alors d'ajouter ou de retirer des éléments ou de modifier les éléments existants si ceux-ci ne sont pas des objets.
La fonction renvoie l'objet passé en argument, elle ne crée pas une copie « gelée ».
Exemples
>Geler des objets
var obj = { prop: function () {}, toto: "truc",};// On peut ajouter de nouvelles propriétés,// éditer ou supprimer celles existantesobj.toto = "machin";obj.bidule = "woof";delete obj.prop;// L'argument et la valeur renvoyée correspondent au// même objet.// Il n'est pas nécessaire d'utiliser la valeur renvoyée// pour geler l'objet original.var o = Object.freeze(obj);o === obj; // trueObject.isFrozen(obj); // true// Maintenant que l'objet est gelé, les changements échouerontobj.toto = "eheh"; // échoue silencieusementobj.roxor = "ga bu zo meu"; // échoue silencieusement et n'ajoute// pas la propriété// ...en mode strict, l'échec se traduira par une exception TypeErrorsfunction echec() { "use strict"; obj.toto = "bipbip"; // renvoie une TypeError delete obj.toto; // renvoie une TypeError delete obj.roxor; // renvoie true car l'attribut n' a pas été ajouté obj.bipbip = "arf"; // renvoie une TypeError}echec();// Les changements via Object.defineProperty échoueront également// renvoie une TypeErrorObject.defineProperty(obj, "ohoh", { value: 17 });// renvoie une TypeErrorObject.defineProperty(obj, "toto", { value: "eit" });// Il est également impossible de modifier le prototype.// Les deux instructions suivantes déclencheront une TypeError.Object.setPrototypeOf(obj, { x: 20 });obj.__proto__ = { x: 20 };Geler un tableau
let a = [0];Object.freeze(a);// Le tableau ne peut plus être modifiéa[0] = 1; // échoue silencieusementa.push(2); // échoue silencieusement// en mode strict, de telles tentatives// déclencheront des exceptions TypeErrorfunction echec() { "use strict"; a[0] = 1; a.push(2);}echec();L'exemple qui suit illustre comment les propriétés qui sont des objets peuvent être éditées (la méthodefreeze ne s'applique que sur l'objet courant et de façon superficielle).
obj1 = { internal: {},};Object.freeze(obj1);obj1.internal.a = "valeurA";obj1.internal.a; // 'valeurA'L'objet qui est gelé est immuable mais ce n'est pas nécessairement une constante. Pour obtenir une constante, il faut que l'ensemble des références (directes et indirectes) pointe vers des objets immuables. Les chaînes de caractères, les nombres et les booléens sont toujours immuables. La plupart du temps, on aura besoin de créer des constantes au cas par cas (et non de façon générale).
Qu'est-ce que le gel « superficiel » ? (shallow freeze)
Lorsqu'on appelleObject.freeze(monObjet), le gel ne s'applique qu'aux propriétés directement rattachées àmonObjet. L'ajout, la suppression ou la réaffectation ne sont empêchées que sur l'objet directement. Si les valeurs de ces propriétés sont également des objets, ces derniers ne sont pas gelés et on peut leur ajouter/supprimer/réaffecter des valeurs.
var employé = { nom: "Leroy", designation: "Développeur", adresse: { cp: "72000", ville: "Le Mans", },};Object.freeze(employé);employé.nom = "John"; // propriété directe, la réaffectation échoue en silenceemployé.adresse.ville = "Paris"; // propriété d'un objet fils : modifiableconsole.log(employé.adresse.ville); // affichera ParisPour rendre l'objet complètement immuable, on gèle chacun des objets qu'il contient. Voici un exemple simple de fonction pour parcourir les propriétés qui sont des objets et les geler (attention, cela ne gère pas le cas où on a des cycles de références, ce qui entraînerait une boucle infinie).
function deepFreeze(obj) { // On récupère les noms des propriétés définies sur obj var propNames = Object.getOwnPropertyNames(obj); // On gèle les propriétés avant de geler l'objet for (let name of propNames) { let value = obj[name]; obj[name] = value && typeof value === "object" ? deepFreeze(value) : value; } // On gèle l'objet initial return Object.freeze(obj);}obj2 = { internal: { a: null, },};deepFreeze(obj2);obj2.internal.a = "valeurB"; // échouera silencieusement en mode non-strictobj2.internal.a; // nullNotes
Pour ES5, si l'argument passé à la méthode n'est pas un objet mais est d'un autre type primitif, cela entraînera une exceptionTypeError. Pour ECMAScript 2015 (ES2015), un argument qui n'est pas un objet sera traité comme un objet ordinaire gelé et sera renvoyé tel quel par la méthode.
Object.freeze(1);// TypeError: 1 is not an object - code ES5Object.freeze(1);// 1 - code ES2015Geler unArrayBufferView contenant des éléments entraînera une exceptionTypeError car ce sont des vues sur des zones mémoires.
> Object.freeze(new Uint8Array(0)) // Aucun élémentUint8Array []> Object.freeze(new Uint8Array(1)) // Avec des élémentsTypeError: Cannot freeze array buffer views with elements> Object.freeze(new DataView(new ArrayBuffer(32))) // Aucun élémentDataView {}> Object.freeze(new Float64Array(new ArrayBuffer(64), 63, 0)) // Aucun élémentFloat64Array []> Object.freeze(new Float64Array(new ArrayBuffer(64), 32, 2)) // Avec des élémentsTypeError: Cannot freeze array buffer views with elementsOn notera que les trois propriétés standard (buf.byteLength,buf.byteOffset etbuf.buffer) sont en lecture seule (comme pourArrayBuffer etSharedArrayBuffer) : il n'y a donc aucune raison de vouloir geler ces propriétés.
Comparaison avecObject.seal()
Lorsqu'on utilise la méthodeObject.freeze(), les propriétés existantes d'un objet deviennent immuables. En revanche, avecObject.seal(), il est toujours possible de modifier la valeur des propriétés existantes d'un objet scellé.
Spécifications
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-object.freeze> |