Ostateczny przewodnik po Getters i Setterach w JavaScript
Getters i Setery są funkcje lub metody używane do dostać i zestaw wartości zmiennych. Koncepcja getter-setter to powszechne w programowaniu komputerowym: prawie wszystkie języki programowania wysokiego poziomu zawierają zestaw składni do implementacji pobierających i ustawiających, w tym JavaScipt.
W tym poście zobaczymy, co ustawiają gettery i jak to zrobić tworzyć i używać ich w JavaScript.
Układarki i enkapsulacja
Pomysł getterów i setterów jest zawsze wspomniany w połączeniu z hermetyzacją. Enkapsulacja może być rozumiany na dwa sposoby.
Po pierwsze, jest to ustawienie ustawiacze danych aby uzyskać dostęp i zmodyfikować te dane. Ta definicja jest przydatna, gdy niektóre operacje, takie jak walidacja, muszą być wykonane na danych przed zapisaniem lub przeglądaniem it-gettery i settery stanowią dla niego idealny dom.
Po drugie, istnieje bardziej restrykcyjna definicja, według której dokonuje się hermetyzacji ukryj dane, aby uczynić go niedostępnym z innego kodu, z wyjątkiem tych, którzy zaatakowali i ustawili. W ten sposób nie skończymy przypadkowo nadpisując ważne dane z innym kodem w programie.
Twórz gettery i settery
1. Z metodami
Ponieważ gettery i setery są zasadniczo działa które pobierają / zmieniają wartość, są więcej niż jeden sposób tworzyć i używać ich. Pierwszy sposób to:
var obj = foo: 'to wartość foo', getFoo: function () return this.foo; , setFoo: function (val) this.foo = val; console.log (obj.getFoo ()); // "to jest wartość foo" obj.setFoo ('hello'); console.log (obj.getFoo ()); // "dzień dobry"
To jest najprostszy sposób do tworzenia pobierających i ustawiających. Jest nieruchomość bla
i są dwie metody: getFoo
i setFoo
do zwróć i przypisz wartość do tej nieruchomości.
2. Ze słowami kluczowymi
Więcej “urzędnik” i solidnym sposobem tworzenia getterów i setterów jest użycie dostać
i zestaw
słowa kluczowe.
Do stwórz gettera, Umieść dostać
słowo kluczowe przed deklaracją funkcji, która posłuży jako metoda gettera i użyje zestaw
słowo kluczowe w ten sam sposób utwórz seter. Składnia jest następująca:
var obj = fooVal: 'to jest wartość foo', pobierz foo () return this.fooVal; , set foo (val) this.fooVal = val; console.log (obj.foo); // "to jest wartość foo" obj.foo = 'hello'; console.log (obj.foo); // "dzień dobry"
Pamiętaj, że dane mogą być tylko przechowywane pod nazwą właściwości (fooVal
) to jest różne z nazwy metod getter-setter (bla
) ponieważ właściwość zawierająca getter-setter nie mogę przechowywać danych także.
Która droga jest lepsza?
Jeśli wybierzesz tworzenie getterów i setterów ze słowami kluczowymi, możesz użyć operator przypisania do ustawiania danych i operator dot, aby uzyskać dane, w taki sam sposób, w jaki uzyskasz dostęp / ustaw wartość zwykłej nieruchomości.
Jeśli jednak wybierzesz pierwszy sposób kodowania getterów i setterów, musisz wywołać metody setter i getter przy użyciu składni wywołania funkcji ponieważ są to typowe funkcje (nic specjalnego jak te utworzone za pomocą dostać
i zestaw
słowa kluczowe).
Jest też szansa, że przypadkowo się skończysz przypisanie innej wartości do właściwości, które zawierały te metody ustawiania gettera i całkowicie je stracić! Coś, o czym nie musisz się martwić w późniejszej metodzie.
Więc widzisz, dlaczego powiedziałem druga technika jest bardziej solidna.
Zastąp zapobieganie
Jeśli z jakiegoś powodu wolisz pierwszą technikę, spraw, aby właściwości trzymały metody getter-setter tylko czytać tworząc je za pomocą Object.defineProperties
. Właściwości utworzone przez Object.defineProperties
, Object.defineProperty
i Reflect.defineProperty
automatycznie skonfigurować do zapisywalny: false
co znaczy tylko czytać:
/ * Zapobiegaj nadpisywaniu * / var obj = foo: 'to jest wartość foo'; Object.defineProperties (obj, 'getFoo': value: function () return this.foo;, 'setFoo': value: function (val) this.foo = val;); obj.getFoo = 66; // getFoo nie zostanie zastąpione! console.log (obj.getFoo ()); // „to jest wartość foo”
Operacje wewnątrz getterów i setterów
Po wprowadzeniu getterów i setterów możesz iść dalej wykonywać operacje na danych przed zmianą lub zwrotem.
W poniższym kodzie w funkcji getter dane są połączony ze sznurkiem przed zwróceniem, aw funkcji ustawiającej sprawdzanie poprawności czy wartość jest liczbą, czy nie jest wykonywany przed aktualizacją n
.
var obj = n: 67, get id () return ”Identyfikator to: '+ this.n; , set id (val) if (typeof val === 'number') this.n = val; console.log (obj.id); // "Identyfikator to: 67" obj.id = 893; console.log (obj.id); // "Identyfikator to: 893" obj.id = 'hello'; console.log (obj.id); // "Identyfikator to: 893"
Chroń dane za pomocą pobierających i ustawiających
Do tej pory omówiliśmy użycie getterów i setterów w pierwszym kontekście enkapsulacji. Przejdźmy do drugiego, czyli jak to zrobić ukryj dane z zewnętrznego kodu z pomocą getterów i seterów.
Niezabezpieczone dane
Ustawienie getterów i setterów nie oznacza, że dostęp do danych można uzyskać i zmienić tylko za pomocą tych metod. W poniższym przykładzie jest to zmieniono bezpośrednio bez dotykania metod getter i setter:
var obj = fooVal: 'to jest wartość foo', pobierz foo () return this.fooVal; , set foo (val) this.fooVal = val; obj.fooVal = 'hello'; console.log (obj.foo); // "dzień dobry"
Nie korzystaliśmy z setera, ale bezpośrednio zmienił dane (fooVal
). Dane, które początkowo ustawiliśmy w środku obj
już nie ma! Aby zapobiec temu (przypadkowo), ty potrzebuję ochrony dla twoich danych. Możesz dodać to przez ograniczenie zakresu gdzie dostępne są twoje dane. Możesz to zrobić albo przez zakres blokowania lub zakres funkcji.
1. Blokuj zakres
Jednym ze sposobów jest użyj zakresu bloków wewnątrz którego dane zostaną zdefiniowane za pomocą pozwolić
słowo kluczowe, które ogranicza jego zakres do tego bloku.
ZA zakres bloku można utworzyć, umieszczając swój kod wewnątrz pary nawiasów klamrowych. Zawsze, gdy tworzysz zakres bloków, upewnij się zostaw komentarz powyżej, prosząc o pozostawienie szelek w spokoju, aby nikt usuwa szelki przez pomyłkę myśląc, że są to dodatkowe zbędne nawiasy klamrowe w kodzie lub dodaj etykietę do zakresu bloku.
/ * BLOKOWY ZAKRES, pozostaw same klamry! * / let fooVal = 'to jest wartość foo'; var obj = get foo () return fooVal; , set foo (val) fooVal = val fooVal = 'hello'; // nie wpłynie na fooVal wewnątrz bloku console.log (obj.foo); // „to jest wartość foo”
Zmiana / tworzenie fooVal
poza blokiem nie wpłynie fooVal
odesłany w ustawieniach gettera.
2. Zakres funkcji
Bardziej powszechnym sposobem ochrony danych za pomocą zakresu jest przechowywanie danych wewnątrz funkcji i zwracając obiekt z getterami i setterami z tej funkcji.
funkcja myobj () var fooVal = 'to jest wartość foo'; return get foo () return fooVal; , set foo (val) fooVal = val fooVal = 'hello'; // nie wpłynie na nasz oryginalny fooVal var obj = myobj (); console.log (obj.foo); // „to jest wartość foo”
Obiekt (za pomocą bla()
getter-setter w środku) zwrócony przez myobj ()
funkcja jest zapisane w obj
, i wtedy obj
jest wykorzystywany do wywołaj getter i setter.
3. Ochrona danych bez określania zakresu
Istnieje również inny sposób ochrony danych przed nadpisaniem bez ograniczania jego zakresu. Logika, która się za tym kryje, wygląda następująco: jak możesz zmienić dane, jeśli nie wiesz, co się nazywa?
Jeśli dane mają nie tak łatwo powtarzalna nazwa zmiennej / właściwości, Są szanse, że nikt (nawet my sami) nie nadpisze go, przypisując jakąś wartość do tej zmiennej / nazwy właściwości.
var obj = s89274934764: 'to jest wartość foo', pobierz foo () return this.s89274934764; , set foo (val) this.s89274934764 = val; console.log (obj.foo); // „to jest wartość foo”
Widzisz, to jeden ze sposobów na rozwiązanie. Chociaż nazwa, którą wybrałem, nie jest naprawdę dobra, możesz również użyj losowych wartości lub symboli tworzyć nazwy nieruchomości, jak zaproponował Derick Bailey w tym wpisie na blogu. Głównym celem jest ukryj dane z innego kodu i pozwól parom ustawiającym getter na dostęp / aktualizację.
Kiedy należy używać getterów i setterów?
Teraz pojawia się wielkie pytanie: czy zaczynasz przypisywać gettery i settery do wszystkich twoich danych teraz?
Jeśli jesteś ukrywanie danych, wtedy jest Nie ma innego wyboru.
Ale jeśli twoje dane są widziane przez inny kod, wszystko jest w porządku, czy nadal musisz używać ustawników getters po prostu spakuj to z kodem który wykonuje na nim niektóre operacje? Powiedziałbym tak. Kod dodaje się bardzo szybko. Tworzenie mikro jednostek pojedynczych danych za pomocą własnego gettera zapewnia pewną niezależność pracować nad wymienionymi danymi bez wpływu na inne części kodu.