Object.freeze()
wydaje się być przejściową wygodną metodą przejścia do stosowania const
w ES6.
Czy są przypadki, w których oba zajmują swoje miejsce w kodzie lub czy istnieje preferowany sposób pracy z niezmiennymi danymi?
Czy powinienem używać Object.freeze()
wszystkich przeglądarek, z którymi współpracuję, a const
potem przełączyć się na ich używanie const
?
javascript
ecmascript-6
Siergiej Baszarow
źródło
źródło
Object.isFrozen
ale także są one ich własne prymitywny typ danych ...)Odpowiedzi:
const
iObject.freeze
to dwie zupełnie różne rzeczy.const
dotyczy powiązań („zmiennych”). Tworzy niezmienne powiązanie, tj. Nie można przypisać nowej wartości do powiązania.Object.freeze
działa na wartościach , a dokładniej na wartościach obiektów . Czyni obiekt niezmiennym, tj. Nie można zmienić jego właściwości.źródło
const
jest nowyvar
; ma tylko zasięg blokowy i zapobiega zmianie przypisania. Możesz użyćlet
, ale naprawdę musisz to zrobić tylko wtedy, gdy zamierzasz zmienić wartość, na którą wskazuje zmienna, co ma sens w przypadku zmiennych sterujących pętlą / iteratorów i prostych typów, takich jak liczby i łańcuchy, ale nie w przypadku większości zastosowań obiektów (w tym tablice). Jeśli chcesz mieć obiekt / tablicę, której zawartość nie może być zmieniona, to oprócz zadeklarowania goconst
powinieneś również wywołaćObject.freeze()
go.const
NIE jest nowyvar
,let
jest nowyvar
W ES5
Object.freeze
nie działa na prymitywach, które prawdopodobnie byłyby częściej deklarowane przy użyciuconst
niż obiektów. Możesz zamrażać prymitywy w ES6, ale masz też wsparcie dlaconst
.Z drugiej strony
const
deklarowanie obiektów nie "zamraża" ich, po prostu nie możesz ponownie zadeklarować całego obiektu, ale możesz dowolnie modyfikować jego klucze. Z drugiej strony możesz ponownie deklarować zamrożone obiekty.Object.freeze
jest również płytka, więc trzeba by ją rekurencyjnie stosować do obiektów zagnieżdżonych, aby je chronić.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
źródło
ob1.bar.value = 4; // (frozen) modified, because ob1.bar is nested
: Czy wynika to z zakresu metody?Podsumowanie:
const
iObject.freeze()
służą zupełnie innym celom.const
służy do deklarowania zmiennej, która musi zostać przypisana od razu i nie może być ponownie przypisana. zmienne zadeklarowane przezconst
mają zakres blokowy, a nie zakres funkcji, jak zmienne zadeklarowane za pomocąvar
Object.freeze()
jest metodą, która akceptuje obiekt i zwraca ten sam obiekt. Teraz nie można usunąć żadnych właściwości obiektu ani dodać nowych właściwości.Przykłady
const
:Przykład 1: nie można ponownie przypisać
const
const foo = 5; foo = 6;
Poniższy kod zgłasza błąd, ponieważ próbujemy ponownie przypisać zmienną foo, która została zadeklarowana za pomocą
const
słowa kluczowego, nie możemy jej ponownie przypisać.Przykład 2: Struktury danych, do których są przypisane,
const
można modyfikować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
W tym przykładzie deklarujemy zmienną za pomocą
const
słowa kluczowego i przypisujemy do niej obiekt. Chociaż nie możemy ponownie przypisać tej zmiennej o nazwie object, możemy zmutować sam obiekt. Jeśli zmienimy istniejące właściwości lub dodamy nowe właściwości, będzie to miało skutek. Aby wyłączyć wszelkie zmiany w obiekcie, których potrzebujemyObject.freeze()
.Przykłady
Object.freeze()
:Przykład 1: Nie można zmutować zamrożonego obiektu
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
W tym przykładzie, gdy wywołujemy
Object.freeze()
i podajemyobject1
jako argument, funkcja zwraca obiekt, który jest teraz „zamrożony”. Jeśli porównamy odniesienie nowego obiektu do starego obiektu za pomocą===
operatora, możemy zauważyć, że odnoszą się one do tego samego obiektu. Również, gdy próbujemy dodać lub usunąć jakiekolwiek właściwości, widzimy, że nie ma to żadnego efektu (w trybie ścisłym pojawi się błąd).Przykład 2: Obiekty z odniesieniami nie są w pełni zamrożone
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);
Ten przykład pokazuje, że właściwości obiektów zagnieżdżonych (i innych przez referencyjne struktury danych) są nadal modyfikowalne . Więc
Object.freeze()
nie „zamraża” w pełni obiektu, gdy ma właściwości, które są referencjami (np. Tablice, obiekty).źródło
var obj = { a: 1, b: 2 }; Object.freeze(obj); obj.newField = 3; // You can't assign new field , or change current fields
Powyższy przykład całkowicie czyni twój obiekt niezmiennym.
Spójrzmy na następujący przykład.
const obj = { a: 1, b: 2 }; obj.a = 13; // You can change a field obj.newField = 3; // You can assign new field.
To nie da żadnego błędu.
Ale jeśli spróbujesz w ten sposób
const obj = { a: 1, b: 2 }; obj = { t:4 };
Zostanie wyświetlony błąd taki jak „obj jest tylko do odczytu”.
Inny przypadek użycia
const obj = {a:1}; var obj = 3;
Będzie rzucać
Duplicate declaration "obj"
Również zgodnie z wyjaśnieniem mozilla docs const
Te przykłady zostały utworzone zgodnie z funkcjami babeljs ES6.
źródło
Niech będzie proste.
Oni są różni. Sprawdź komentarze do kodu, które wyjaśnią każdy przypadek.
Const
- Jest to zmienna o zasięgu blokowymlet
, której wartość nie może zostać ponownie przypisana, ponownie zadeklarowana.To znaczy
{ 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
Rozumie się, że const ma zasięg blokowy, a jego wartość nie jest ponownie przypisywana.
Object.freeze
: Właściwości katalogu głównego obiektu są niezmienne, również nie możemy dodawać i usuwać więcej właściwości, ale możemy ponownie przypisać cały obiekt.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
// Jedna rzecz, która jest podobna w obu przypadkach, to fakt, że zagnieżdżone obiekty są zmienne
const obj1 = {nested :{a:10}}; var obj2 = Object.freeze({nested :{a:10}}); obj1.nested.a = 20; // both statement works obj2.nested.a = 20;
Dzięki.
źródło