web-dev-qa-db-fra.com

Différence entre gel et sceau

Je viens d'entendre parler des méthodes JavaScript freeze et seal, qui peuvent être utilisées pour rendre n'importe quel objet immuable.

Voici un exemple court d'utilisation:

var o1 = {}, o2 = {};
Object.freeze(o2);

o1["a"] = "worked";
o2["a"] = "worked";

alert(o1["a"]);   //prints "worked"
alert(o2["a"]);   //prints "undefined"

Quelle est la différence entre freeze et seal? Peuvent-ils augmenter les performances?

143
maja

Object.seal

  • Cela empêche d'ajouter et/ou de supprimer des propriétés de l'objet scellé; en utilisant delete retournera false
  • Cela rend chaque propriété existante non configurable : elles ne peuvent pas être converties de "descripteurs de données" en "descripteurs d'accesseurs" (et vice versa), et aucun attribut de descripteurs d'accesseurs ne peut être modifié ( les descripteurs peuvent changer leur attribut writable et leur attribut value si writeable est vrai).
  • Peut lancer un TypeError lors d'une tentative de modification de la valeur de l'objet scellé lui-même (le plus souvent en mode strict)

Object.freeze

  • Exactement quoi Object.seal fait, plus:
  • Il empêche la modification de any propriétés existantes

Ni l'un ni l'autre n'affecte les objets "profonds"/petits-enfants. Par exemple, si obj est gelé, obj.el ne peut pas être réaffecté, mais la valeur de obj.el pourrait être modifié, par exemple obj.el.id peut être changé.


Performance:

Le scellement ou le gel d’un objet peut affecter sa vitesse d’énumération, selon le navigateur:

  • Firefox: les performances d'énumération ne sont pas impactées
  • IE: l'impact sur les performances de dénombrement est négligeable
  • Chrome: les performances d'énumération sont plus rapides avec les objets scellés ou gelés
  • Safari: les objets scellés ou congelés sont 92% plus lents (à partir de 2014)

Tests: objets scellés , objets gelés .

176
Niccolò Campolungo

J'ai écrit un projet test qui compare ces 3 méthodes:

  • Object.freeze()
  • Object.seal()
  • Object.preventExtensions()

Mes tests unitaires couvrent les cas CRUD:

  • [C] ajouter une nouvelle propriété
  • [R] lu existé propriété
  • [U] modifier une propriété existante
  • [D] retirer une propriété existante

Résultat:

enter image description here

89
piecioshka

Vous pouvez toujours les rechercher dans MDN. En bref:

  • Freeze : rend l'objet immuable, ce qui signifie qu'aucun changement de propriété définie n'est autorisé, sauf s'il s'agit d'objets.
  • Seal : empêche l'ajout de propriétés, mais les propriétés définies peuvent toujours être modifiées.
80
tungd

Object.freeze() crée un objet gelé, ce qui signifie qu'il prend un objet existant et appelle essentiellement Object.seal(), mais il marque également toutes les propriétés de “data accessor” comme étant writable:false, de sorte que leurs valeurs ne peuvent pas être changées. - Kyle Simpson, vous ne savez pas JS - Prototypes This & Object

8
shmuli

J'examinais les différences entre Freeze et Seal dans ECMAScript 5 et ai créé un script pour clarifier les différences. Gelé crée un objet immuable comprenant des données et une structure. Seal empêche les modifications apportées aux interfaces nommées - pas d’ajouts, de suppressions - mais vous pouvez muter l’objet et redéfinir la signification de son interface.

function run()
{
    var myObject = function() 
    { 
        this.test = "testing"; 
    }

    //***************************SETUP****************************

    var frozenObj = new myObject();
    var sealedObj = new myObject();

    var allFrozen = Object.freeze(frozenObj);
    var allSealed = Object.seal(sealedObj);
    alert("frozenObj of myObject type now frozen - Property test= " + frozenObj.test);
    alert("sealedObj of myObject type now frozen - Property test= " + sealedObj.test);

    //***************************FROZEN****************************

    frozenObj.addedProperty = "added Property"; //ignores add
    alert("Frozen addedProperty= " + frozenObj.addedProperty);
    delete frozenObj.test; //ignores delete
    alert("Frozen so deleted property still exists= " + frozenObj.test);
    frozenObj.test = "Howdy"; //ignores update
    alert("Frozen ignores update to value= " + frozenObj.test);
    frozenObj.test = function() { return "function"; } //ignores
    alert("Frozen so ignores redefinition of value= " + frozenObj.test);

    alert("Is frozen " + Object.isFrozen(frozenObj));
    alert("Is sealed " + Object.isSealed(frozenObj));
    alert("Is extensible " + Object.isExtensible(frozenObj));

    alert("Cannot unfreeze");
    alert("result of freeze same as the original object: " + (frozenObj === allFrozen).toString());

    alert("Date.now = " + Date.now());

    //***************************SEALED****************************

    sealedObj.addedProperty = "added Property"; //ignores add
    alert("Sealed addedProperty= " + sealedObj.addedProperty);
    sealedObj.test = "Howdy"; //allows update
    alert("Sealed allows update to value unlike frozen= " + sealedObj.test);
    sealedObj.test = function() { return "function"; } //allows
    alert("Sealed allows redefinition of value unlike frozen= " + sealedObj.test);
    delete sealedObj.test; //ignores delete
    alert("Sealed so deleted property still exists= " + sealedObj.test);
    alert("Is frozen " + Object.isFrozen(sealedObj));
    alert("Is sealed " + Object.isSealed(sealedObj));
    alert("Is extensible " + Object.isExtensible(sealedObj));

    alert("Cannot unseal");
    alert("result of seal same as the original object: " + (sealedObj === allSealed).toString());

    alert("Date.now = " + Date.now());
}
3
Jaycee

Je sais que je peux être un peu en retard mais

  • Similarité: les deux servent à créer objets non extensibles.
  • Différence: En gel configurable, énumérable et accessible en écriture les attributs de l'objet sont définis sur false. où comme dans Sealed accessible en écriture l'attribut est défini sur true et le reste des attributs est faux.
2
Faisal Naseer

Vous pouvez maintenant forcer une propriété d'objet unique à être gelée au lieu de geler l'objet entier. Vous pouvez y parvenir avec Object.defineProperty avec writable: false en tant que paramètre.

var obj = {
    "first": 1,
    "second": 2,
    "third": 3
};
Object.defineProperty(obj, "first", {
    writable: false,
    value: 99
});

Dans cet exemple, obj.first a maintenant sa valeur verrouillée à 99.

0
jaggedsoft