This article has been localized into Czech by the community.
gettery a settery
V předchozím článku o polích třídy jsme viděli, jak můžeme ukládat data na třídě deklarováním pole a poté k němu na instancích třídy velmi snadno přistupovat. Například jsme takto ukládali a používali pole "name" (jméno):
class Dog
{
name = "Dog Doe";
}
let dog = new Dog();
dog.name = "John Dog";
alert(dog.name);
Všimněte si, jak deklaruji pole jména uvnitř třídy a poté později změním hodnotu z instance třídy Dog, kterou vytvoříme. Jednoduché a snadné!
Někdy však nechcete, aby byl přístup k vašim polím takto jednoduchý. Například v příkladu výše bych jako spotřebitel třídy mohl nastavit jméno na cokoli od divného čísla po prázdný řetězec - opravdu není žádný způsob, jak kontrolovat, co se s tímto polem stane.
Pokud ale uplatníme koncept getterů a setterů, my jako tvůrci třídy, si můžeme tuto kontrolu vzít zpět. S gettery a settery v podstatě přidáváte vrstvu funkcionalit mezi pole a spotřebitele třídy, což vám umožňuje plně kontrolovat, co se s polem stane. To se často označuje jako zapouzdření dat.
gettery
Gettery i settery jsou v podstatě jen funkce, ale jsou předponovány klíčovými slovy get (získat) a set (nastavit), aby byl zdůrazněn jejich speciální význam. Začněme pohledem na gettery - zde je jejich základní forma:
class Dog
{
#name = "Dog Doe";
get name()
{
return this.#name;
}
}
Především si všimněte, že jsem změnil název pole na #name. To, jak jsme se naučili v článku o polích, naznačuje, že pole je nyní soukromé, což v podstatě brání přístupu k němu z vnějšku třídy.
Poté deklarujeme metodu nazvanou name() (jméno), předponovanou klíčovým slovem get (získat). Uvnitř metody vrátíme hodnotu pole #name. Protože je metoda name() deklarována s klíčovým slovem get, můžeme k ní přistupovat, jako by to byla vlastnost, z vnějšku třídy:
class Dog
{
#name = "Dog Doe";
get name()
{
return this.#name;
}
}
let dog = new Dog();
alert(dog.name);
Nyní jsme definovali getter, ale ne setter, což v podstatě naše pole činí pouze pro čtení. Uvidíte to, pokud se pokusíte změnit hodnotu pole - nic se nestane:
class Dog
{
#name = "Dog Doe";
get name()
{
return this.#name;
}
}
let dog = new Dog();
dog.name = "John Dog";
alert(dog.name); // Still "Dog Doe"
Pokud chceme být schopni změnit hodnotu #name z vnějšku třídy, nyní potřebujeme definovat také setter.
settery
Takže přidáme do třídy setter. Je předponován klíčovým slovem set (nastavit), a na rozdíl od metody get, přijímá parametr, kterým je hodnota přiřazená k poli. Můžete jej nazvat jakkoliv chcete - v mém příkladu jsem parametr nazval "val" (hodnota):
class Dog
{
#name = "Dog Doe";
get name()
{
return this.#name;
}
set name(val)
{
this.#name = val;
}
}
let dog = new Dog();
dog.name = "John Dog";
alert(dog.name); // John Dog
Jak vidíte, nyní máme možnost přiřadit novou hodnotu k poli #name z vnějšku třídy - kdykoli to uděláme, je volána metoda set name(), kde můžeme přiřadit novou hodnotu k poli.
Přidání logiky
Jednou z největších výhod používání getterů a setterů je možnost přidat logiku do metod, což vám umožňuje zpracování hodnot před jejich vrácením nebo přiřazením. To je obzvláště užitečné pro setter, kde můžete validovat hodnotu před jejím přiřazením k poli, ale může být také použito pro getter, například pro formátování vrácené hodnoty před jejím vrácením.
S tímto na mysli jsem výše vytvořil novou verzi příkladu, kde přidáváme logiku jak do getteru, tak do setteru, abychom vám ukázali, jak mocná tato funkce je:
class Dog
{
#name;
get name()
{
let arr = this.#name.split(' ');
arr = arr.map(function(part)
{
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
});
return arr.join(" ");
}
set name(val)
{
val = val.trim();
if(val == '')
throw new Error("Empty value not allowed!");
this.#name = val;
}
}
let dog = new Dog();
dog.name = prompt("Please enter dog name:");
alert("Name of dog: " + dog.name);
Tento příklad je trochu složitější, než musí být, ale rozhodl jsem se vám ukázat něco užitečného místo něčeho jednoduchého. Používám několik technik a metod popsaných jinde v tomto tutoriálu, ale pokud jste o nich ještě nečetli, nebojte se - později se tomu budeme věnovat.
V metodě get zajistíme, že je jméno správně naformátováno. Vypadá to trochu složitě, ale jednoduše rozdělíme jméno na části, například na křestní jméno a příjmení, a poté se ujistíme, že pro každou část je první znak velkým písmenem a zbytek znaků malými písmeny. Takže, pokud lidé zadají jméno jako "jOHN DoE", stejně vyjde "John Doe". K tomu použijeme několik metod polí a řetězců - přečtěte si o nich více v článcích o polích a řetězcích.
V metodě set provádíme velmi jednoduchou validaci kontrolou, zda uživatel odeslal prázdnou hodnotu, a pokud ano, vyvoláme chybu (více o chybách a procesu jejich vyvolání později). Vyvoláním chyby zabráníme přiřazení hodnoty k poli #name. Snadno byste mohli přidat více validací, jako je kontrola, zda uživatel odeslal křestní jméno a příjmení atd.
Shrnutí
Speciální get a set metody vám umožňují získat úplnou kontrolu nad polem třídy. Pro spotřebitele třídy to stále vypadá jako jednoduché pole, ke kterému mohou přistupovat jako ke kterémukoli jinému poli, ale v zákulisí jsou volány get a set metody, což vám, tvůrci třídy, umožňuje manipulovat s hodnotou při vstupu a výstupu z třídy.