web-dev-qa-db-fra.com

Object.freeze () vs const

Object.freeze() semble être une méthode de transition pratique pour utiliser const dans ES6. 

Existe-t-il des cas où les deux prennent leur place dans le code ou existe-t-il un moyen privilégié de travailler avec des données immuables?

Devrais-je utiliser Object.freeze() jusqu'au moment où tous les navigateurs avec lesquels je travaille supportent const puis basculent vers const à la place?

80
Sergei Basharov

const et Object.freeze sont deux choses complètement différentes.

const s'applique à bindings ("variables"). Cela crée une liaison immuable, c’est-à-dire que vous ne pouvez pas attribuer une nouvelle valeur à la liaison.

Object.freeze fonctionne sur values ​​, et plus spécifiquement, object values ​​. Cela rend un objet immuable, c’est-à-dire que vous ne pouvez pas modifier ses propriétés.

155
Felix Kling

Dans ES5, Object.freeze ne fonctionne pas sur les primitives, qui seraient probablement plus communément déclarées à l'aide de const que d'objets. Vous pouvez geler les primitives dans ES6, mais vous avez également le support de const.

Par contre, const utilisé pour déclarer des objets ne les "gèle" pas, vous ne pouvez simplement pas redéclarer l'objet entier, mais vous pouvez modifier ses clés librement. D'autre part, vous pouvez redéclarer des objets gelés.

Object.freeze est également superficiel, vous devez donc l'appliquer de manière récursive sur des objets imbriqués pour les protéger.

var ob1 = {
   foo : 1,
    bar : {
        value : 2   
    }
};
Object.freeze( ob1 );

const ob2 = {
   foo : 1,
    bar : {
        value : 2   
    }
}

ob1.foo = 4;  // (frozen) ob1.foo not modified
ob2.foo = 4;  // (const) ob2.foo modified

ob1.bar.value = 4;  // (frozen) modified, because ob1.bar is nested
ob2.bar.value = 4;  // (const) modified

ob1.bar = 4;  // (frozen) not modified, bar is a key of obj1
ob2.bar = 4;  // (const) modified

ob1 = {};  // (frozen) ob1 redeclared
ob2 = {}; // (const) ob2 not redeclared
61
pawel
var obj = {
  a: 1,
  b: 2
};
Object.freeze(obj);
obj.newField = 3; // You can't assign new field , or change current fields

L'exemple ci-dessus rend complètement votre objet immuable. 

Regardons l'exemple suivant.

const obj = {
  a: 1,
  b: 2
};
obj.a = 13; // You can change a field
obj.newField = 3; // You can assign new field.

Cela ne provoquera aucune erreur.

Mais si vous essayez comme ça

const obj = {
      a: 1,
      b: 2
    };
obj = {
 t:4
};

Une erreur comme celle-ci "obj est en lecture seule".

Un autre cas d'utilisation 

const obj = {a:1};
var obj = 3;

Il va jeter Duplicate declaration "obj"

Toujours selon mozilla docs const explication

La déclaration const crée une référence en lecture seule à une valeur. Il ne signifie pas que la valeur qu’elle détient est immuable, uniquement que le identificateur de variable ne peut pas être réaffecté.

_ {Cet exemple créé en fonction des fonctionnalités de babeljs ES6.} _

10
İlker Korkut

Résumé:

const et Object.freeze() servent des objectifs totalement différents. 

  • const est là pour déclarer une variable qui doit être analysée immédiatement et ne peut pas être réaffectée. les variables déclarées par const ont une portée de bloc et non une fonction, comme les variables déclarées avec var
  • Object.freeze() est une méthode qui accepte un objet et retourne le même objet. Désormais, aucune de ses propriétés ne peut être supprimée de l'objet, ni aucune nouvelle propriété ajoutée.

Exemples const:

Exemple 1: Impossible de réaffecter const

const foo = 5;

foo = 6;

Le code suivant renvoie une erreur car nous essayons de réaffecter la variable foo déclarée avec le mot clé const. Nous ne pouvons pas le réaffecter.

Exemple 2: les structures de données affectées à const peuvent être mutées

const object = {
  prop1: 1,
  prop2: 2 
}

object.prop1 = 5;   // object is still mutable!
object.prop3 = 3;   // object is still mutable!

console.log(object);  // object is mutated

Dans cet exemple, nous déclarons une variable à l'aide du mot clé const et lui affectons un objet. Bien que nous ne puissions pas réaffecter à cette variable appelée objet, nous pouvons muter l'objet lui-même. Si nous changeons les propriétés existantes ou ajoutons de nouvelles propriétés, cela aura un effet. Pour désactiver toute modification de l'objet, nous avons besoin de Object.freeze().

Exemples Object.freeze():

Exemple 1: impossible de muter un objet gelé

object1 = {
  prop1: 1,
  prop2: 2
}

object2 = Object.freeze(object1);

console.log(object1 === object2); // both objects are refer to the same instance

object2.prop3 = 3; // no new property can be added, won't work

delete object2.prop1; // no property can be deleted, won't work

console.log(object2); // object unchanged

Dans cet exemple, lorsque nous appelons Object.freeze() et donnons object1 comme argument, la fonction retourne l'objet qui est maintenant 'gelé'. Si nous comparons la référence du nouvel objet à l'ancien, à l'aide de l'opérateur ===, nous pouvons constater qu'ils se réfèrent au même objet. De même, lorsque nous essayons d'ajouter ou de supprimer des propriétés, nous pouvons voir que cela n'a aucun effet (les erreurs se produiront en mode strict).

Exemple 2: les objets avec des références ne sont pas entièrement gelés

const object = {
  prop1: 1,
  nestedObj: {
    nestedProp1: 1,
    nestedProp2: 2,
  } 
}


const frozen = Object.freeze(object);

frozen.prop1 = 5; // won't have any effect
frozen.nestedObj.nestedProp1 = 5; //will update because the nestedObject isn't frozen

console.log(frozen);

Cet exemple montre que les propriétés des objets imbriqués (et autres par les structures de données de référence) sont sont toujours mutables . Donc, Object.freeze() ne "gèle" pas complètement l’objet quand il a des propriétés qui sont des références (par exemple, Tableaux, Objets).

6
Willem van der Veen

Soyons simples.

Ils sont différents . Vérifiez les commentaires sur le code, qui expliquera chaque cas.

Const - Il s'agit d'une variable de portée de bloc comme let, dont la valeur ne peut pas être réaffectée, déclarée à nouveau.

Cela signifie

{
 const val = 10;  // you can not access it out side this block , block scope variable

}

console.log(val); // undefined because it is block scope 

const constvalue = 1;
constvalue = 2; // will give error as we are reassigning the value;
const obj = { a:1 , b:2};

obj.a = 3;
obj.c = 4;
console.log(obj); // obj = {a:3,b:2,c:4} we are not assigning the value of identifier we can 
                  // change the object properties , const applied only on value, not with properties
obj = {x:1};     // error you are reassigning the value of constant obj 
obj.a = 2 ;     // you can add ,delete element of object

Nous comprenons tout à fait que const est une portée de bloc et que sa valeur n'est pas réaffectée.

Object.freeze: Les propriétés de la racine de l’objet ne sont pas modifiables. Nous ne pouvons pas non plus ajouter ni supprimer d’autres propriétés, mais nous pouvons réaffecter l’ensemble de l’objet.

var x = Object.freeze({data:1,
    name:{
    firstname:"hero", lastname:"nolast"
    }
});

x.data = 12;  // the object properties can not be change but in const you can do
x.firstname ="adasd"; // you can not add new properties to object but in const you can do

x.name.firstname = "dashdjkha"; // The nested value are changeable 

//The thing you can do in Object.freeze but not in const

x = { a: 1};  // you can reassign the object when it is Object.freeze but const its not allowed

// Une chose similaire dans les deux cas, les objets imbriqués sont modifiables

const obj1 = {nested :{a:10}};
var obj2 =  Object.freeze({nested :{a:10}});

obj1.nested.a = 20; // both statement works
obj2.nested.a = 20;

Merci.

0
Himanshu sharma