Ultimativ guide til Getters og Setters i JavaScript
getters og settere er funktioner eller metoder der bruges til få og sæt værdierne af variabler. Getter-setter konceptet er fælles i computer programmering: næsten alle programmeringssprog på højt niveau leveres med et sæt syntaxer til implementering af getters og settere, herunder JavaScipt.
I dette indlæg vil vi se, hvad getters setters er, og hvordan Opret og brug dem i JavaScript.
Getters-setters and encapsulation
Ideen om getters og settere er altid nævnt i forbindelse med indkapsling. Indkapsling kan være forstået på to måder.
For det første er det oprettelsen af data-getters-settere trio for at få adgang til og ændre disse data. Denne definition er nyttig, når nogle operationer, såsom validering, skal være udført på dataene før du gemmer eller ser det - getters og settere giver det perfekte hjem til det.
For det andet er der en strengere definition, hvormed indkapsling gøres skjul data, for at gøre den utilgængelig fra anden kode, undtagen gennem getters og setters. På denne måde slutter vi ikke ved et uheld overskrive vigtige data med en anden kode i programmet.
Opret getters og setters
1. Med metoder
Da getters og setters er grundlæggende funktioner der henter / ændrer en værdi, der er mere end en måde at oprette og bruge dem. Den første måde er:
var obj = foo: 'dette er værdien af foo', getFoo: funktion () return this.foo; , setFoo: funktion (val) this.foo = val; console.log (obj.getFoo ()); // "dette er værdien af foo" obj.setFoo ('hej'); console.log (obj.getFoo ()); // "Hej"
Dette er den enkleste måde at skabe getters og setters. Der er en ejendom foo
og der er to metoder: getFoo
og setFoo
til returnere og tildele en værdi til den ejendom.
2. med søgeord
En mere “officiel” og robust måde at skabe getters og setters på er at bruge få
og sæt
søgeord.
Til lav en getter, placere få
søgeord foran en funktionserklæring, der vil tjene som getter-metoden, og bruge sæt
søgeord på samme måde til lav en setter. Syntaxen er som følger:
var obj = fooVal: 'dette er værdien af foo', få foo () return this.fooVal; , sæt foo (val) this.fooVal = val; console.log (obj.foo); // "dette er værdien af foo" obj.foo = 'hej'; console.log (obj.foo); // "Hej"
Bemærk at dataene kun kan være gemt under et ejendomsnavn (fooVal
) det er forskellige fra navnet på getter-setter metoderne (foo
) fordi en ejendom, der holder getter-setteren kan ikke holde dataene såvel.
Hvilken vej er bedre?
Hvis du vælger at oprette getters og setters med søgeord, kan du bruge opgaveoperatør til at indstille dataene og dot operator for at hente dataene, på samme måde som du ville få adgang til / indstille værdien af en almindelig ejendom.
Men hvis du vælger den første metode til kodning af getters og settere, skal du ringe til setter og getter metoder ved hjælp af funktionsopkaldssyntaxen fordi de er typiske funktioner (intet særligt som dem der er skabt ved hjælp af få
og sæt
søgeord).
Der er også en chance for at du måske ender ved et uheld tildele en anden værdi til de ejendomme, der holdt disse getter-setter metoder og miste dem helt! Noget du ikke behøver at bekymre sig om i den senere metode.
Så kan du se, hvorfor jeg sagde anden teknik er mere robust.
Overskrivningsforebyggelse
Hvis du af en eller anden grund foretrækker den første teknik, skal du gøre ejendommene indeholdende getter-setter-metoderne Læs kun ved at oprette dem ved brug af Object.defineProperties
. Egenskaber oprettet via Object.defineProperties
, Object.defineProperty
og Reflect.defineProperty
konfigurere automatisk til skrivbar: false
hvilket betyder Læs kun:
/ * Overskrivningsforebyggelse * / var obj = foo: 'dette er værdien af foo'; Object.defineProperties (obj, 'getFoo': værdi: funktion () return this.foo;, 'setFoo': værdi: funktion (val) this.foo = val;); obj.getFoo = 66; // getFoo kommer ikke til at blive overskrevet! console.log (obj.getFoo ()); // "dette er værdien af foo"
Operationer indenfor getters og setters
Når du har introduceret getters og setters, kan du gå videre og udføre operationer på dataene før du skifter eller returnerer det.
I koden nedenfor er dataene i getter-funktionen sammenkædet med en streng før returnering, og i setterfunktionen en validering af om værdien er et tal eller ej udføres før opdatering n
.
var obj = n: 67, få id () return 'ID'et er:' + this.n; , sæt id (val) if (type of val === 'number') this.n = val; console.log (obj.id); // "ID'et er: 67" obj.id = 893; console.log (obj.id); // "ID'et er: 893" obj.id = 'hej'; console.log (obj.id); // "ID'et er: 893"
Beskyt data med getters og setters
Hidtil dækkede vi brugen af getters og settere i den første kontekst af indkapsling. Lad os gå videre til den anden, dvs. hvordan skjul data fra udenfor kode ved hjælp af getters og setters.
Ubeskyttede data
Oprettelsen af getters og setters betyder ikke, at dataene kun kan fås og ændres via disse metoder. I det følgende eksempel er det ændret direkte uden at berøre getter og setter metoder:
var obj = fooVal: 'dette er værdien af foo', få foo () return this.fooVal; , sæt foo (val) this.fooVal = val; obj.fooVal = 'hej'; console.log (obj.foo); // "Hej"
Vi brugte ikke setter men direkte ændret data (fooVal
). De data, vi oprindeligt satte inde obj
er væk nu! For at forhindre, at dette sker (ved et uheld), du har brug for en vis beskyttelse til dine data. Du kan tilføje det ved begrænser omfanget af hvor dine data er tilgængelige. Du kan gøre det ved enten blokere scoping eller funktion scoping.
1. Blok scoping
En måde er at Brug en blokomfang inden for hvilket dataene vil blive defineret ved hjælp af lade
søgeord som begrænser dets anvendelsesområde til den blok.
EN blokere omfang kan oprettes ved at placere din kode inde i et par krøllede seler. Når du opretter en blokomfang, sørg for at Efterlad en kommentar over det, der beder om bøjlerne at blive efterladt alene, så ingen fjerner bøjlerne fejlagtigt tænker de er nogle ekstra overflødige braces i koden eller Tilføj en etiket til blokomfanget.
/ * BLOCK SCOPE, lad armbåndene være alene! * / let fooVal = 'dette er værdien af foo'; var obj = get foo () return fooVal; , sæt foo (val) fooVal = val fooVal = 'hej'; // ikke vil påvirke fooVal inde i blok console.log (obj.foo); // "dette er værdien af foo"
Ændring / skabe fooVal
uden for blokken vil ikke påvirke det fooVal
henvist inde i getters setters.
2. Funktionsscoping
Den mere almindelige måde at beskytte dataene med scoping på er at holde dataene inde i en funktion og returnerer en genstand med getters og setters fra den funktion.
funktion myobj () var fooVal = 'dette er værdien af foo'; return get foo () return fooVal; , sæt foo (val) fooVal = val fooVal = 'hej'; // ikke vil påvirke vores oprindelige fooVal var obj = myobj (); console.log (obj.foo); // "dette er værdien af foo"
Objektet (med foo ()
getter-setter inde i det) returneret af myobj ()
funktion er gemt i obj
, og så obj
er vant til ring til getter og setter.
3. Databeskyttelse uden scoping
Der er også en anden måde, du kan beskytte dine data mod at blive overskrevet uden at begrænse dens anvendelsesområde. Logikken bag den går som sådan: Hvordan kan du ændre et stykke data, hvis du ikke ved hvad der hedder?
Hvis dataene har en Ikke så let reproducerbar variabel / ejendomsnavn, chancerne er ingen (selv os selv) kommer til at ende med at overskrive det ved at tildele nogen værdi til den variabel / ejendoms navn.
var obj = s89274934764: 'dette er værdien af foo', få foo () returnér dette.s89274934764; , sæt foo (val) this.s89274934764 = val; console.log (obj.foo); // "dette er værdien af foo"
Se, det er en måde at arbejde tingene på. Selvom navnet jeg valgte er ikke rigtig godt, kan du også Brug tilfældige værdier eller symboler at oprette ejendomsnavne som det er foreslået af Derick Bailey i dette blogindlæg. Hovedmålet er at hold dataene skjulte fra anden kode og lad et getter-setter-par få adgang til / opdatere det.
Hvornår skal du bruge getters og settere?
Nu kommer det store spørgsmål: begynder du at tildele getters og settere til alle dine data nu?
Hvis du er skjule data, så er der intet andet valg.
Men hvis dine data ses af anden kode, er det fint, skal du stadig bruge gettersettere bare for at pakke det sammen med kode der udfører nogle operationer på det? jeg ville sige Ja. Kode tilføjer meget snart. Oprettelse af mikroenheder af individuelle data med sin egen getter-setter giver dig en vis uafhængighed at arbejde på de nævnte data uden at påvirke andre dele af koden.