Obiekt.freeze () vs const

Object.freeze() wygląda na przejściową metodę wygody, aby przejść do używania const w ES6.

Czy są przypadki, w których oba mają swoje miejsce w kodzie lub czy istnieje preferowany sposób pracy z niezmiennymi danymi?

Czy powinienem użyć Object.freeze() do momentu, gdy wszystkie przeglądarki działają z obsługą const, a następnie przełączyć się na użycie const zamiast?

Author: Sergei Basharov, 2015-10-14

4 answers

const i Object.freeze to dwie zupełnie różne rzeczy.

const dotyczy wiązań ("zmienne"). Tworzy niezmienne powiązanie, tzn. 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 . Sprawia, że obiekt jest niezmienny, tzn. nie można zmienić jego właściwości.

 123
Author: Felix Kling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 14:25:03

W ES5 Object.freeze nie działa na prymitywach, które prawdopodobnie częściej byłyby deklarowane za pomocą const niż obiektów. Możesz zamrozić prymitywy w ES6, ale wtedy masz również wsparcie dla const.

Z drugiej strony const używane do deklarowania obiektów nie "zamraża" ich, po prostu nie można ponownie zadeklarować całego obiektu, ale można dowolnie modyfikować jego klucze. Z drugiej strony możesz ponownie zgłosić zamrożone obiekty.

Object.freeze jest również płytka, więc musisz ją rekurencyjnie zastosować na zagnieżdżonym przedmioty do ich ochrony.

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
 52
Author: pawel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-17 20:03:52
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 poniższy 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.

But If you try like that

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

Wyświetli błąd w stylu "obj jest tylko do odczytu".

Kolejny przypadek użycia

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

Rzuci Duplicate declaration "obj"

Również według mozilla docs const Wyjaśnienie

Deklaracja const tworzy odniesienie tylko do odczytu do wartości. It nie oznacza, że posiadana przez niego wartość jest niezmienna , jedynie, że identyfikator zmiennej nie może być ponownie przypisany.

ten przykład stworzony zgodnie z funkcjami babeljs ES6.

 9
Author: İlker Korkut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 11:59:22

Podsumowanie:

const i Object.freeze() służą zupełnie innym celom.

  • const czy istnieje możliwość deklarowania zmiennej, która musi być od razu przypisana i nie może być przypisana. zmienne zadeklarowane przez const mają zakres blokowy, a nie zakres funkcji, jak zmienne zadeklarowane przez var
  • {[5] } jest metodą, która akceptuje obiekt i zwraca ten sam obiekt. Teraz obiekt nie może mieć usuniętych żadnych właściwości ani żadnych nowych właściwości dodano.

Przykłady const:

Przykład 1: nie można ponownie przypisać const

const foo = 5;

foo = 6;

Poniższy kod wyświetla błąd, ponieważ próbujemy ponownie przypisać zmienną foo, która została zadeklarowana za pomocą słowa kluczowego const, nie możemy jej przypisać.

Przykład 2: struktury danych przypisane do const mogą być zmutowane

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ą używając słowa kluczowego const i Przypisz do niego obiekt. Chociaż nie możemy ponownie przypisać do 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 wpływ. Aby wyłączyć wszelkie zmiany w obiekcie potrzebujemy Object.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łamy Object.freeze() i podamy object1 jako argument funkcja zwraca obiekt, który jest teraz "frozen" 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 staramy się dodać lub usunąć jakiekolwiek właściwości możemy zobaczyć, że to nie ma żadnego efektu (rzuci błąd w trybie ścisłym).

Przykład 2: obiekty z referencjami nie są całkowicie 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 zagnieżdżonych obiektów (i innych według danych referencyjnych struktury) są nadal mutowalne . Tak więc Object.freeze() nie "zamrozi" w pełni obiektu, gdy ma właściwości będące referencjami (np. tablic, obiektów).

 1
Author: Willem van der Veen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-15 15:38:44