Object.freeze()

La méthode Object.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é ».

Syntaxe

Object.freeze(obj)

Paramètres

obj
L'objet à geler.

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 exception TypeError (la plupart du temps en mode strict).

Les propriétés qui sont des données ne pourront pas être changées. 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.

Exemples

var obj = {
  prop: function (){},
  toto: "truc"
};

// On peut ajouter de nouvelles propriétés, éditer ou supprimer celles existantes
obj.toto = "machin";
obj.bidule = "woof";
delete obj.prop;

// L'argument et la valeur renvoyée seront tous les deux gelés.
// Il n'est pas nécessaire d'utiliser la valeur renvoyée
// pour geler l'objet original.
var o = Object.freeze(obj);


// Maintenant que l'objet est gelé, les changements échoueront
obj.toto = "eheh"; // échoue silencieusement
obj.roxor = "ga bu zo meu"; // échoue silencieusement et n'ajoute pas la propriété

// ...en mode strict, l'échec se traduira par une exception TypeErrors
function echec(){
  "use strict";
  obj.toto = "bipbip"; // renvoie une TypeError
  delete obj.roxor;    // renvoie une TypeError
  obj.bipbip = "arf";  // renvoie une  TypeError
}

echec();

// Les changements via Object.defineProperty échoueront également
Object.defineProperty(obj, "ohoh", { value: 17 }); // renvoie une  TypeError
Object.defineProperty(obj, "toto", { value: "eit" }); // renvoie une  TypeError

L'exemple qui suit illustre comment les propriétés qui sont des objets peuvent être éditées (la méthode freeze 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'

// Pour rendre l'objet complètement immuable, on 
// gèle chaque objet qu'il contient.
// Pour ce faire, on utilise cette fonction.
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
  propNames.forEach(function(name) {
    var prop = obj[name];

    // On gèle prop si c'est un objet
    if (typeof prop == 'object' && prop !== null && !Object.isFrozen(prop))
      deepFreeze(prop);
  });

  // On gèle l'objet initial
  return Object.freeze(obj);
}

obj2 = {
  internal: {}
};

deepFreeze(obj2);
obj2.internal.a = 'valeurB';
obj2.internal.a; // undefined

Notes

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 exception TypeError. Pour ECMAScript 2015 (ES6), 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 ES5

Object.freeze(1);
// 1                             - code ES6

Spécifications

Spécification Statut Commentaires
ECMAScript 5.1 (ECMA-262)
La définition de 'Object.freeze' dans cette spécification.
Standard Définition initiale.
Implémentée avec JavaScript 1.8.5
ECMAScript 2015 (6th Edition, ECMA-262)
La définition de 'Object.freeze' dans cette spécification.
Standard  
ECMAScript 2017 Draft (ECMA-262)
La définition de 'Object.freeze' dans cette spécification.
Projet  

Compatibilité des navigateurs

Fonctionnalité Firefox (Gecko) Chrome Internet Explorer Opera Safari
Support simple 4.0 (2) 6 9 12 5.1
Fonctionnalité Firefox Mobile (Gecko) Android IE Mobile Opera Mobile Safari Mobile
Support simple ? ? ? ? ?

Voir aussi

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : SphinxKnight, ChristopheBoucaut
 Dernière mise à jour par : SphinxKnight,