3 proste sposoby na niezmienność w JavaScript

fsgeek.pl 4 lat temu

Stałe wartości mogą być zainicjalizowane tylko jeden raz i od tej pory nie można ich zmienić. Dzięki temu zawsze wiemy, co jest w środku, więc jest to odporniejsze na błędy. A jak można zapewnić niezmienność danych w JavaScript?

Javascript-exercises

Jeśli już teraz wiesz, jakie to są sposoby, to sprawdź swoje umiejętności w specjalnie przygotowanych ćwiczeniach z JavaScript. Stworzyłem repozytorium z testami, które mają pomóc w nauce i sprawdzić wiedzę. Sprawdź swoją wiedzę już teraz

Const

Na sam początek sposób, który przychodzi w sposób naturalny od wprowadzenia ES6, czyli const. Nie jest to jednak stała w sensie, jaki znamy z innych języków programowania. Jest to bardziej stałość referencji, czyli raz zainicjalizowanej zmiennej nie możemy zainicjalizować ponownie ani przypisać nowej wartości. Sprawdza się to dla typów prostych np.: string czy number. Zyskują one tym samym niezmienność. Natomiast jeżeli pod zmienną mamy zainicjalizowany obiekt albo tablicę to możemy ciągle modyfikować wartości wewnątrz. Najlepiej to widać na poniższym przykładzie:

const a = 1; a = 2; //Uncaught TypeError: Assignment to constant variable. const b = {a: 1}; b = {b: 2}; //Uncaught TypeError: Assignment to constant variable. b.a = 2; // {a: 2} delete b.a // {} const c = [1]; c = [2]; //Uncaught TypeError: Assignment to constant variable. c[1] = 2; // [1,2]

Object.seal()

Na szczęście to nie wszystko i mamy inne sposoby zapewnienia stałości obiektu. Pierwszym z nich jest Object.seal(). Powoduje on, iż obiekt jest zamknięty przed modyfikacjami. Nie możemy dodawać nowych ani usuwać istniejących własności. Ciągle możemy jednak zmieniać wartości istniejących adekwatności.

const a = Object.seal({a: 1}); a.b = 2; // {a: 1} a.a = 2; // {a: 2} delete a.b; // {a: 2}

Co interesujące nazwa jest trochę myląca, ponieważ możemy to też aplikować do tablic. Tak samo, jak w przypadku tablic, nie możemy dodawać nowych elementów, ale możemy zmieniać istniejące.

const a = Object.seal([1]); a[1] = 2; // [1] a[0] = 2; // [2]

Object.freeze()

Na sam koniec zostawiłem Object.freeze(), który jest najbardziej restrykcyjny. Jak nazwa wskazuje, powoduje "zamrożenie" obiektu. Oprócz ograniczeń wprowadzonych już przez Object.seal() tutaj dodatkowo nie możemy zmieniać wartości istniejących obiektów. Obiekt jest teraz prawdziwie niemutowalny.

const a = Object.freeze({a: 1}); a.b = 2; // {a: 1} a.a = 2; // {a: 1} delete a.a; // {a: 1}

Podobnie możemy to zaaplikować do tablic.

const a = Object.freeze([1]); a[1] = 2; // [1] a[0] = 2; // [1]

Zagnieżdżone obiekty

Trzeba uważać, jeżeli zagnieżdżamy obiekty w sobie. Taki zagnieżdżony obiekt nie jest już zabezpieczony przed zmianami. Najprościej to zobaczyć na przykładzie

const a = Object.freeze({a: 1, b: {c:1}}) a.b.c = 2 // {a: 1, b: {c:2}}

Jeśli chcemy mieć prawdziwie stały obiekt, to musimy na każdym poziomie zapewnić, iż obiekty/tablice będą zamrożone.

Idź do oryginalnego materiału