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?
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.
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
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.} _
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.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()
.
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).
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.