Getters and Setters in JavaScript

Mosh Hamedani

Follow

joulukuu 29, 2019 – 5 min read

Käsite getterit ja setterit on varsin yleinen nykyisin käytössä olevissa suosituissa kielissä. Oletko koskaan tarvinnut varmistaa, että tietty toiminto suoritetaan aina ennen tai jälkeen jonkin arvon antamisen objektin ominaisuudelle? Tämä on mahdollista settereiden avulla. Voit myös suorittaa mitä tahansa käsittelyä hakiessasi ominaisuuden arvoa käyttämällä gettereitä (esim. muotoilu). Yksi tapa toteuttaa getterit ja setterit on käyttää metodeja, kuten Javassa tehdään. ES5:stä lähtien meillä on kuitenkin käytettävissä paljon tyylikkäämpi ja käytännöllisempi vaihtoehto käyttämällä get– ja set-syntaksia. No, aloitetaanpa!

Javaskriptissä oliot ovat ominaisuuksien kokoelmia, ja olet luultavasti käyttänyt niitä tietojen tallentamiseen ennenkin. Ominaisuus on yksinkertaisesti avain-arvopari. Tässä on esimerkki:

const options = {
timeout: 5000,
retries: 3,
ip: '192.168.1.20',
port: 4001,
};

Objektin ominaisuuksia voi helposti asettaa ja lukea, esimerkiksi näin:

artist.name = 'Carice Anouk van Houten';console.log(artist.name); //=> "Carice Anouk van Houten"

Tämäkään ei varmasti ole mitään uutta, jos sinulla on jo jonkin verran kokemusta JavaScriptistä. Jotta voimme tehdä eron näiden tavallisten ominaisuuksien ja toisen tyyppisten ominaisuuksien välillä, joita tulemme näkemään tässä artikkelissa, voimme kutsua ensin mainittuja ”data-ominaisuuksiksi”.

Getterit ja setterit: vanha tapa

Ennen ES5:tä ainoa tapa toteuttaa getterit ja setterit oli käyttää tavallisia metodeja. Kuten alla olevassa esimerkissä:

Olen säilyttänyt funktion avainsanan yllä olevassa esimerkissä tehdäkseni selväksi, että tässä ei ole mitään taikuutta. Vain tavallisia metodeja. Olisimme voineet saavuttaa saman vaikutuksen käyttämällä ES2015:n metodimäärittelyn syntaksia, joka on lyhyempi ja hieman tyylikkäämpi:

const config = {
_port: 4001,
setPort(port) {
// ...
},
getPort() {
// ...
},
};

Tällaisten gettereiden ja settereiden käyttö on melko yksinkertaista:

config.setPort(8080);
console.log(config.getPort()); //=> 8080

Arvon inkrementointi tehtäisiin näin:

item.setQuantity(item.getQuantity() + 1);

Mikä näyttää todella pitkäveteiseltä verrattuna siihen, että ominaisuutta inkrementoitaisiin suoraan:

item.quantity += 1;
// Or even simpler...
item.quantity++;

Getterit ja setterit: miksi?

OOO-kielissä, kuten Javassa, C++:ssa tai C#:ssa, on mahdollista paljastaa luokan jäsenet eri tasoilla käyttämällä access modifiereita (kuten public, protected ja private). Tämä palvelee OOP:n tärkeän konseptin eli datan piilottamisen toteuttamista.

Ensimmäisissä kielissä hyvin yleinen gettereiden ja settereiden käyttö on luokan jäsenten paljastaminen turvallisella tavalla. Voit esimerkiksi toteuttaa vain getterin varmistaaksesi, että yksityistä jäsentä ei koskaan muuteta luokan ulkopuolelta. Asettajaa puolestaan voidaan käyttää validoimaan annetut arvot ja säilyttämään kyseisen luokan instanssien eheys.

Miten on JavaScript?

Javaskriptissa asiat ovat hieman toisin. Tätä artikkelia kirjoitettaessa JS:ssä ei ole access modifiereita. Tällä hetkellä paras vaihtoehto, joka meillä on, on käyttää symboleja, jotka antavat meille jonkinasteisen yksityisyyden, kun niitä käytetään avaimina. Jotkut ihmiset eivät kuitenkaan pidä niistä. Etenkin siksi, että tätä yksityisyyttä on helppo rikkoa käyttämällä heijastusta.

En pidä tätä todellisena ongelmana, koska kielet, joissa on heijastusta, antavat yleensä ohjelmoijille mahdollisuuden rikkoa kapselointia jollain tavalla. Ongelma jonka näen symboleissa on se, että niitä ei ole niin käytännöllinen käyttää kuin yksinkertainen yksityinen accessor olisi. Hyvä uutinen on, että EcmaScript-ehdotus, joka sisältää yksityiset kentät, on jo vaiheessa 3. Ja ne tulevat olemaan immuuneja kaikenlaiselle heijastukselle.

Edellisen kappaleen esimerkissä emme käyttäneet symboleja tai mitään muutakaan kikkaa simuloidaksemme yksityistä jäsentä. _port-ominaisuudella ei sinänsä ole mitään erityistä. Se on ihan tavallinen dataominaisuus, ja sellaisenaan se voidaan asettaa tai lukea suoraan ohittaen täysin luomamme getterin ja setterin.

Koska symbolien ja muiden kapselointitekniikoiden selittäminen ei ole tämän artikkelin tarkoitus, en toteuta sen koodiesimerkkeihin yksityisiä ominaisuuksia. Pidä vain mielessä, että gettereitä ja settereitä käytetään yleisesti (mutta ei aina) tarjoamaan pääsy kapseloituihin jäseniin. Huomaa lopuksi _port-ominaisuuden nimen edessä oleva alleviivaus. Se on JS-kehittäjien keskuudessa de facto konventio, joka ilmaisee, että tietty ominaisuus on yksityinen eikä sitä saa käyttää sen luokan ulkopuolelta, jossa se on määritelty.

Getterit ja setterit: uusi tapa accessor-ominaisuuksilla

Accessor-ominaisuudet ovat nykyaikainen tapa määritellä getterit ja setterit. Määrittelynsä osalta ne eivät juuri eroa edellisestä esimerkistämme, mutta niiden käyttö on todella erilaista. Mukautetaan ensin koodimme käyttämään accessor-ominaisuuksia:

Kuten näet, vain kaksi asiaa on muuttunut tässä esimerkissä:

  • Metodien setPort ja getPort sijasta. Käytämme set– ja get-syntaksia sekä yhtä nimeä ominaisuudelle (”port”, tässä esimerkissä)
  • Me emme tarvitse function-avainsanaa tässä. Itse asiassa, jos yrität käyttää sitä, saat SyntaxError-virheen.

Miten käyttää accessor-ominaisuuksia?

Jos accessor-ominaisuuden määritelmä on melko samanlainen kuin se, miten luomme vanhan koulukunnan gettereitä ja settereitä, niiden käytöllä ei ole mitään näkyvää eroa siihen, miten käytämme tavallisia dataominaisuuksia:

config.port = 8080;
console.log(config.port); //=> 8080

Ja näin näyttää inkrementti-ilmaisu:

timer.seconds += 1;

Ja. Se on niin yksinkertaista. =)

Johtopäätös

  • Objektit ovat ominaisuuksien kokoelmia
  • Säännöllinen ominaisuus on vain avain-arvopari ja sitä voidaan kutsua ”dataominaisuudeksi”
  • Voit toteuttaa getterit ja setterit tavallisina metodeina. Tämä on ”vanhan koulukunnan” tapa JavaScriptissä.
  • Gettereitä ja settereitä käytetään tavallisesti tarjoamaan pääsy luokan yksityisiin jäseniin.
  • Accessor-ominaisuudet voivat käyttäytyä täsmälleen samoin kuin vanhoihin tavallisiin metodeihin perustuvat getterit ja setterit, mutta niiden käyttö on suunniteltu niin, että ne näyttävät data-ominaisuuksilta.

Tahdotko hallita JavaScriptin? Suosittelen lämpimästi Moshin JavaScript-kursseja.

Jos pidit tästä artikkelista, jaa se myös muille!

Vastaa

Sähköpostiosoitettasi ei julkaista.