Object.freeze () vs const

136

Object.freeze()scheint eine vorübergehende Bequemlichkeitsmethode für die Verwendung constin ES6 zu sein.

Gibt es Fälle, in denen beide ihren Platz im Code einnehmen, oder gibt es eine bevorzugte Methode, um mit unveränderlichen Daten zu arbeiten?

Sollte ich Object.freeze()bis zu dem Moment alle Browser verwenden, mit denen ich unterstütze const, und conststattdessen auf die Verwendung wechseln ?

Sergei Basharov
quelle
2
Ich habe mich daran gemacht, babeljs in meinem Erstellungsprozess zu verwenden, damit ich solche Kompatibilitätsprobleme hauptsächlich ignorieren kann.
spender
22
Nein - sie machen verschiedene Dinge. const verhindert eine Neuzuweisung (z. B. können Sie nicht const x = 1; x = 2); Einfrieren verhindert Mutation (zB können Sie Object.freeze (x) nicht; xa = 2);
Joews
Sie sind sich nicht sicher, ob es sinnvoll ist, dies zu einer neuen Frage zu machen oder sie hier nur anzugehen, aber ich wäre auch neugierig, ob es große Unterschiede zwischen Symbols und Object.freeze gibt. Ich fühle mich sind sie auch im Zusammenhang (dh Symbole als gefrorene ausgewertet werden aus , Object.isFrozenaber sie sind auch ihre eigenen primitiven Datentyp ...)
August
Die Mutation wird nur für die erste Ebene verhindert, sodass Sie Object.freeze (x) nicht ausführen können. xa = 2, aber Sie KÖNNEN Object.freeze (x); xab = 2. Siehe jsfiddle.net/antimojv/op6ea91w/8 . Verwenden Sie für ein vollständiges Einfrieren Ad-hoc-Bibliotheken
Antimo

Antworten:

229

constund Object.freezesind zwei völlig verschiedene Dinge.

constgilt für Bindungen ("Variablen"). Es wird eine unveränderliche Bindung erstellt, dh Sie können der Bindung keinen neuen Wert zuweisen.

Object.freezearbeitet mit Werten und insbesondere mit Objektwerten . Es macht ein Objekt unveränderlich, dh Sie können seine Eigenschaften nicht ändern.

Felix Kling
quelle
3
Grundsätzlich constist das neue var; Es ist nur blockbezogen und verhindert eine Neuzuweisung. Sie können verwenden let, müssen dies aber nur, wenn Sie den Wert ändern möchten, auf den eine Variable zeigt. Dies ist sinnvoll für Schleifensteuerungs- / Iteratorvariablen und einfache Typen wie Zahlen und Zeichenfolgen, jedoch nicht für die meisten Verwendungen von Objekten (einschließlich Arrays). Wenn Sie ein Objekt / Array möchten, dessen Inhalt nicht geändert werden constkann, sollten Sie es nicht nur mit deklarieren, sondern auch aufrufen Object.freeze().
Mark Reed
constist NICHT das Neue var, letist das Neuevar
Facundo Colombier vor
84

In ES5 Object.freezefunktioniert dies nicht mit Grundelementen , die wahrscheinlich häufiger constals Objekte deklariert werden . Sie können Grundelemente in ES6 einfrieren, haben dann aber auch Unterstützung für const.

constWenn Sie dagegen Objekte deklarieren, werden sie nicht "eingefroren". Sie können einfach nicht das gesamte Objekt neu deklarieren, sondern die Schlüssel frei ändern. Auf der anderen Seite können Sie eingefrorene Objekte neu deklarieren.

Object.freeze ist auch flach, sodass Sie es rekursiv auf verschachtelte Objekte anwenden müssen, um sie zu schützen.

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
pawel
quelle
Diese Erklärung hat so viele meiner Fragen auf einmal geklärt! Zu ob1.bar.value = 4; // (frozen) modified, because ob1.bar is nested: Liegt es am Umfang der Methode?
YCode
14

Zusammenfassung:

constund Object.freeze()dienen ganz anderen Zwecken.

  • constdient zum Deklarieren einer Variablen, die sofort zugewiesen werden muss und nicht neu zugewiesen werden kann. Variablen, die von deklariert wurden, consthaben einen Blockbereich und funktionieren nicht wie Variablen, die mit deklariert wurdenvar
  • Object.freeze()ist eine Methode, die ein Objekt akzeptiert und dasselbe Objekt zurückgibt. Jetzt kann das Objekt keine seiner Eigenschaften entfernen oder neue Eigenschaften hinzufügen.

Beispiele const:

Beispiel 1: Kann nicht neu zugewiesen werden const

const foo = 5;

foo = 6;

Der folgende Code löst einen Fehler aus, da wir versuchen, die Variable foo, die mit dem constSchlüsselwort deklariert wurde, neu zuzuweisen. Wir können sie nicht neu zuweisen.

Beispiel 2: Zugeordnete Datenstrukturen constkönnen mutiert werden

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

In diesem Beispiel deklarieren wir eine Variable mit dem constSchlüsselwort und weisen ihr ein Objekt zu. Obwohl wir dieser Variablen namens object nicht neu zuweisen können, können wir das Objekt selbst mutieren. Wenn wir vorhandene Eigenschaften ändern oder neue Eigenschaften hinzufügen, hat dies Auswirkungen. Um Änderungen am Objekt zu deaktivieren, benötigen wir Object.freeze().

Beispiele Object.freeze():

Beispiel 1: Ein eingefrorenes Objekt kann nicht mutiert werden

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

In diesem Beispiel Object.freeze()gibt object1die Funktion beim Aufrufen und Angeben als Argument das Objekt zurück, das jetzt 'eingefroren' ist. Wenn wir die Referenz des neuen Objekts mit dem ===Operator mit dem alten Objekt vergleichen, können wir feststellen, dass sie sich auf dasselbe Objekt beziehen. Auch wenn wir versuchen, Eigenschaften hinzuzufügen oder zu entfernen, können wir feststellen, dass dies keine Auswirkungen hat (wird im strengen Modus einen Fehler auslösen).

Beispiel 2: Objekte mit Referenzen werden nicht vollständig eingefroren

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);

Dieses Beispiel zeigt, dass die Eigenschaften verschachtelter Objekte (und anderer Referenzdatenstrukturen) weiterhin veränderbar sind . Also Object.freeze()nicht vollständig ‚einfrieren‘ das Objekt , wenn es Eigenschaften aufweist , die Referenzen sind (zum Beispiel Arrays, Objekte).

Willem van der Veen
quelle
12
var obj = {
  a: 1,
  b: 2
};
Object.freeze(obj);
obj.newField = 3; // You can't assign new field , or change current fields

Das obige Beispiel macht Ihr Objekt vollständig unveränderlich.

Schauen wir uns folgendes Beispiel an.

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

Es wird kein Fehler ausgegeben.

Aber wenn du es so versuchst

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

Es wird ein Fehler wie der folgende ausgegeben: "obj ist schreibgeschützt".

Ein weiterer Anwendungsfall

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

Es wird werfen Duplicate declaration "obj"

Auch nach Mozilla Docs const Erklärung

Die const-Deklaration erstellt einen schreibgeschützten Verweis auf einen Wert. Dies bedeutet nicht, dass der darin enthaltene Wert unveränderlich ist , sondern nur, dass die Variablenkennung nicht neu zugewiesen werden kann.

Diese Beispiele wurden gemäß den ES6-Funktionen von babeljs erstellt.

İlker Korkut
quelle
4

Sei einfach.

Sie sind anders. Überprüfen Sie die Kommentare zum Code, die jeden Fall erklären.

Const- Es ist eine Blockbereichsvariable wie let, deren Wert nicht neu zugewiesen werden kann, neu deklariert.

Das bedeutet

{
 const val = 10;  // you can not access it outside 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 re-assigning 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 re-assigning the value of constant obj 
obj.a = 2 ;     // you can add, delete element of object

Das ganze Verständnis ist, dass const ein Blockbereich ist und sein Wert nicht neu zugewiesen wird.

Object.freeze: Die Eigenschaften des Objektstamms sind unveränderlich. Außerdem können wir keine weiteren Eigenschaften hinzufügen und löschen, aber wir können das gesamte Objekt erneut zuweisen.

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

// Eine Sache, die in beiden ähnlich ist, ist, dass verschachtelte Objekte veränderbar sind

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

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

Vielen Dank.

Himanshu Sharma
quelle