Getters and Setters in JavaScript

Mosh Hamedani

Follow

dec. 29, 2019 – 5 min olvasni

A getterek és setterek fogalma meglehetősen elterjedt a ma használatos népszerű nyelvek között. Volt már szüksége arra, hogy biztosítsa, hogy egy adott művelet mindig egy objektum tulajdonságának valamilyen érték hozzárendelése előtt vagy után kerüljön végrehajtásra? Ez a setterekkel lehetséges. A getterek segítségével bármilyen feldolgozást elvégezhetünk egy tulajdonság értékének lekérdezésekor is (pl. formázás). A getterek és setterek implementálásának egyik módja a metódusok használata, ahogyan az a Java-ban történik. Az ES5 óta azonban egy sokkal elegánsabb és praktikusabb alternatíva áll rendelkezésünkre a get és set szintaxis használatával. Nos, kezdjük el!

A JavaScriptben az objektumok tulajdonságok gyűjteményei, és valószínűleg már korábban is használtad őket adatok tárolására. Egy tulajdonság egyszerűen egy kulcs-érték pár. Íme egy példa:

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

A tulajdonságok egy objektumban egyszerűen beállíthatók és kiolvashatók, például így:

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

Még egyszer, ez biztosan nem újdonság, ha már volt némi tapasztalatod a JavaScriptben. Hogy megkülönböztessük ezeket a szabályos tulajdonságokat a másik típustól, amit ebben a cikkben látni fogunk, az előbbieket nevezhetjük “adattulajdonságoknak”.

Getterek és setterek: a régi módszer

Az ES5 előtt a gettereket és settereket csak szabályos metódusokkal tudtuk megvalósítani. Mint az alábbi példában:

A fenti példában megtartottam a function kulcsszót, hogy egyértelmű legyen, hogy itt nincs varázslat. Csak normál metódusok. Ugyanezt a hatást elérhettük volna az ES2015 módszerdefiníciós szintaxisával is, ami rövidebb és valamivel elegánsabb:

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

Az ilyen típusú getterek és setterek használata meglehetősen egyszerű:

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

Egy érték inkrementálása így történne:

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

Ami nagyon terjedelmesnek tűnik, ha összehasonlítjuk egy tulajdonság közvetlen inkrementálásával:

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

Getterek és setterek: miért?

Az olyan OO nyelvekben, mint a Java, a C++ vagy a C#, lehetőség van arra, hogy egy osztály tagjait különböző szinteken tegyük hozzáférhetővé hozzáférési módosítókkal (például public, protected és private). Ez az OOP egyik fontos koncepciójának, az adatelrejtésnek a megvalósítására szolgál.

A getterek és setterek nagyon gyakori használata ezekben a nyelvekben az osztály tagjainak biztonságos módon történő felfedésére. Például csak egy gettert implementálhatunk annak biztosítására, hogy egy privát tagot soha ne lehessen az osztályon kívülről megváltoztatni. A setter viszont használható a megadott értékek érvényesítésére és az adott osztály példányainak integritásának megőrzésére.

Hogyan áll a JavaScript?

A JavaScriptben a dolgok egy kicsit másképp állnak. A cikk megírásának időpontjában a JS-ben nincsenek hozzáférési módosítók. Jelenleg a legjobb lehetőségünk a szimbólumok használata, amelyek bizonyos szintű adatvédelmet biztosítanak, ha kulcsként használjuk őket. Néhányan azonban nem szeretik őket. Különösen azért, mert a reflexió használatával könnyen fel lehet törni ezt a titkosságot.

Nem tartom ezt valódi problémának, mivel azok a nyelvek, amelyekben van reflexió, általában lehetővé teszik a programozók számára, hogy valamilyen módon felbontsák a kapszulázást. A szimbólumokban azt látom a problémát, hogy nem olyan praktikus a használatuk, mint amilyen egy egyszerű privát accessor lenne. A jó hír az, hogy a privát mezőket tartalmazó EcmaScript javaslat már a 3. fázisban van. És ezek immunisak lesznek mindenféle reflexióra.

Az előző szakasz példájában nem használtunk szimbólumokat vagy bármilyen más trükköt a privát tag szimulálására. A _port tulajdonságnak önmagában nincs semmi különleges tulajdonsága. Ez csak egy közönséges adattulajdonság, és mint ilyen, közvetlenül beállítható vagy olvasható, teljesen megkerülve az általunk létrehozott gettert és settert.

Mivel a szimbólumok és egyéb kapszulázási technikák magyarázata nem célja ennek a cikknek, ezért a kódpéldákban nem implementálom a privát tulajdonságokat. Csak tartsuk észben, hogy a gettereket és settereket általában (de nem mindig) a kapszulázott tagokhoz való hozzáférés biztosítására használják. Végezetül figyeljük meg a _port tulajdonság neve előtti aláhúzást. Ez egy de facto konvenció a JS fejlesztők körében, ami azt jelzi, hogy egy adott tulajdonság privát, és nem lehet elérni azon az osztályon kívülről, ahol definiálták.

Getterek és setterek: az új út az accessor tulajdonságokkal

Az accessor tulajdonságok a getterek és setterek definiálásának modern módja. A definíciójukat tekintve nem sokban különböznek az előző példánktól, de a használatuk az, ami igazán más. Először is igazítsuk át a kódunkat az accessor tulajdonságok használatára:

Mint láthatjuk, ebben a példában csak két dolog változott:

  • Az setPort és getPort metódusok helyett. A set és get szintaxist használjuk a tulajdonság egyetlen nevével együtt (“port“, ebben a példában)
  • A function kulcsszóra itt nincs szükségünk. Valójában, ha megpróbáljuk használni, SyntaxError-t kapunk.

Hogyan használjuk a hozzáférési tulajdonságokat?

Ha a hozzáférési tulajdonságok definíciója nagyon hasonló ahhoz, ahogyan a régi iskolai gettereket és settereket létrehozzuk, a használatuk nem mutat látható különbséget ahhoz képest, ahogyan a normál adattulajdonságokat használjuk:

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

És így néz ki egy inkrementálási kifejezés:

timer.seconds += 1;

Igen. Ilyen egyszerű. =)

Következtetés

  • A tárgyak tulajdonságok gyűjteményei
  • A hagyományos tulajdonság csak egy kulcs-érték pár, és nevezhetjük “adattulajdonságnak”
  • A gettereket és settereket normál metódusként implementálhatjuk. Ez a “régi iskola” módja a JavaScriptben.
  • A gettereket és settereket általában arra használják, hogy hozzáférést biztosítsanak egy osztály privát tagjaihoz.
  • Accessor tulajdonságok pontosan úgy viselkedhetnek, mint a régi, szabályos metódus alapú getterek és setterek, de a használatuk úgy van kialakítva, hogy adattulajdonságoknak tűnjenek.

A JavaScriptet szeretné elsajátítani? Nagyon ajánlom a Mosh JavaScript tanfolyamait.

És ha tetszett ez a cikk, oszd meg másokkal is!

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.