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?
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.
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
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.
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 przezconst
mają zakres blokowy, a nie zakres funkcji, jak zmienne zadeklarowane przezvar
- {[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).
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