JavaScript je flexibilní programovací jazyk, který umožňuje vývojářům vytvářet aplikace s využitím funkcionálního, objektově orientovaného i imperativního stylu programování.
Pro podporu objektově orientovaného přístupu JavaScript nabízí koncept tříd. Pochopení jejich fungování je zásadní, proto tento článek slouží jako průvodce, který vysvětlí, co jsou třídy v JavaScriptu a jak se používají.
Co jsou třídy v JavaScriptu?
V objektově orientovaném programování (OOP) je klíčové modelovat systémy jako kolekce interagujících objektů. Objekty uchovávají data pomocí vlastností a provádějí akce prostřednictvím metod. Třída definuje, jaké vlastnosti a metody budou mít objekty určitého typu. Jednoduše řečeno, třídy slouží jako šablony pro vytváření objektů.
Základní pojmy používané ve třídách
Abychom se ujistili, že všichni máme stejné porozumění, definujeme si klíčové pojmy, které budeme v tomto článku používat. Pokud už máte zkušenosti s objektově orientovaným programováním, můžete tuto sekci přeskočit.
❇️ **Třída:** Představuje šablonu pro objekty. Umožňuje vytvářet instance (objekty) s definovanými vlastnostmi a metodami. Vytvoření objektu na základě třídy se nazývá *instanciace*.
❇️ **Člen třídy:** Jakýkoli prvek patřící do třídy. Rozlišujeme dva základní typy členů – metody a vlastnosti.
❇️ **Vlastnost:** Člen třídy sloužící k ukládání dat. Může obsahovat jednoduché hodnoty (čísla, řetězce) nebo komplexnější struktury (objekty, pole).
❇️ **Soukromá vlastnost:** Vlastnost, která je přístupná pouze uvnitř třídy. **Veřejná vlastnost:** Vlastnost, která je přístupná jak uvnitř třídy, tak i mimo ni.
❇️ **Metoda:** Funkce definovaná uvnitř třídy. Metody mají přístup k veřejným i soukromým vlastnostem třídy. Stejně jako vlastnosti rozlišujeme i veřejné a soukromé metody.
❇️ **Gettery a settery:** Speciální metody, které slouží jako rozhraní pro přístup k vlastnostem třídy. Gettery načítají hodnoty vlastností a settery umožňují jejich úpravu.
❇️ **Statické členy:** Členové třídy, kteří jsou přístupní přímo prostřednictvím třídy samotné, nikoli prostřednictvím jejích instancí.
Naopak, **nestatické členy** jsou přístupné pouze prostřednictvím instancí třídy. Před použitím nestatického členu je nutné vytvořit instanci třídy.
Při vytvoření instance třídy se automaticky volá speciální metoda – **konstruktor**. Konstruktor se používá k nastavení počátečních hodnot vlastností instance.
Vysvětlení instanciace třídy
V JavaScriptu vytvoříme instanci třídy pomocí klíčového slova `new` následovaného názvem třídy. Například pro vytvoření instance třídy `Array` použijeme tento kód:
const myArr = new Array()
Vytváření tříd v JavaScriptu
V této části si ukážeme, jak vytvořit třídu, která bude demonstrovat všechny koncepty, o kterých jsme mluvili v sekci o terminologii. Budeme postupovat krok za krokem, přičemž každý příklad bude navazovat na ten předchozí.
Deklarace prázdné třídy
Třídu v JavaScriptu deklarujeme pomocí klíčového slova `class` a určíme její název. Následně definujeme tělo třídy, které je uzavřeno ve složených závorkách a obsahuje všechny členy třídy.
Zde je příklad deklarace třídy s prázdným tělem:
class Dog {
}
Nyní můžeme vytvořit instanci této třídy a vypsat ji do konzole:
const pet = new Dog();
console.log(pet);
Vytváření veřejných vlastností
Veřejné vlastnosti se definují pomocí identifikátoru (názvu) a volitelně s počáteční hodnotou:
class Dog {
name = "Roy";
age;
}
V tomto příkladu jsme definovali vlastnost `name` s počáteční hodnotou řetězce „Roy“ a vlastnost `age` bez počáteční hodnoty.
const pet = new Dog();
console.log(pet.name);
console.log(pet.age);
Definování veřejných metod
Metody můžeme přidávat do třídy uvnitř jejího těla. Metodu definujeme podobně jako funkci, ale vynecháváme klíčové slovo `function`.
class Dog {
name = "Roy";
age;
walk() {
console.log("Walking");
}
}
V tomto příkladu jsme definovali metodu `walk`. Každá instance třídy `Dog` bude mít tuto metodu k dispozici.
const pet = new Dog();
pet.walk();
Přístup k vlastnostem z metod
Obecně přistupujeme k vlastnostem objektu pomocí operátoru tečka. Například, pokud máme objekt s názvem `person` a chceme získat přístup k vlastnosti `name`, uděláme to takto:
person.name
Pokud ale chceme přistupovat k vlastnosti zevnitř metody objektu, použijeme klíčové slovo `this` namísto názvu objektu. Například:
this.name
Klíčové slovo `this` odkazuje na aktuální objekt. Tedy, pokud chceme v rámci metod třídy přistupovat k vlastnostem této třídy, použijeme syntaxi `this.názevVlastnosti`.
Vytváření soukromých vlastností
Předpokládejme, že chceme, aby vlastnosti `name` a `age`, které jsme definovali dříve, byly soukromé. Upravíme definici třídy takto:
class Dog {
#name = "Roy";
#age;
walk() {
console.log("Walking");
}
}
Jak vidíte, soukromé vlastnosti se definují pomocí znaku `#`. Pokud se pokusíte k takové vlastnosti přistoupit mimo třídu, dojde k chybě.
const dog = new Dog();
dog.#name
Vytváření metod getter a setter
Nyní jsou vlastnosti `name` a `age` třídy soukromé. Proto k nim můžeme přistupovat pouze pomocí metod definovaných uvnitř třídy.
Pokud chceme umožnit externímu kódu přístup k těmto vlastnostem, definujeme gettery a settery. Ukážeme si to na vlastnosti `name`:
class Dog {
#name = "Roy";
#age;
get name() {
return this.#name;
}
set name(value) {
this.#name = value;
}
walk() {
console.log("Walking");
}
}
S takto definovanou třídou můžeme nastavit jméno a zobrazit ho pomocí tohoto kódu:
const pet = new Dog();
// Nastavení jména
pet.name = "Rex";
// Získání jména
console.log(pet.name);
Vytváření soukromých metod
Stejně jako soukromé vlastnosti mají i soukromé metody předponu `#`. Deklarace soukromé metody tedy vypadá takto:
class Dog {
#name = "Roy";
#age;
get name() {
return this.#name;
}
set name(value) {
this.#name = value;
}
#increaseAge() {
this.#age++;
}
#decreaseAge() {
this.#age--;
}
walk() {
console.log("Walking");
}
}
Pokud se pokusíte k těmto metodám přistoupit mimo třídu, nebude to fungovat.
const pet = new Dog();
pet.#increaseAge();
Vytvoření metody konstruktoru
Můžeme také definovat metodu konstruktoru. Tato metoda se automaticky volá při vytvoření nové instance třídy. Konstruktor se používá k inicializaci vlastností. V tomto příkladu budeme inicializovat věk a jméno na základě argumentů, které uživatel zadá při vytváření instance.
class Dog {
#name;
#age;
constructor(name = "Dog", age = 0) {
this.#name = name;
this.#age = age;
}
get name() {
return this.#name;
}
set name(value) {
this.#name = value;
}
#increaseAge() {
this.#age++;
}
#decreaseAge() {
this.#age--;
}
walk() {
console.log("Walking");
}
}
Při vytváření instance naší třídy můžeme zadat jméno a věk.
const pet = new Dog('Roy', 3);
console.log(pet.name);
Vytváření statických vlastností a metod
Jak už bylo zmíněno, ke statickým členům lze přistupovat bez nutnosti vytvoření instance třídy. V následujícím příkladu vytvoříme statickou vlastnost a metodu.
class Dog {
#name;
#age;
static genus = "Canis";
constructor(name = "Dog", age = 0) {
this.#name = name;
this.#age = age;
}
static bark() {
console.log("Woof");
}
get name() {
return this.#name;
}
set name(value) {
this.#name = value;
}
#increaseAge() {
this.#age++;
}
#decreaseAge() {
this.#age--;
}
walk() {
console.log("Walking");
}
}
Nyní můžeme přistupovat ke statické vlastnosti a metodě bez vytváření instance:
console.log(Dog.genus);
Dog.bark();
Dědičnost
Třídy mohou dědit vlastnosti z jiných tříd. Třída, která dědí členy z jiné třídy, se nazývá *odvozená třída* (podtřída), zatímco třída, ze které dědí, je *základní třída* (nadřazená třída).
K vytvoření odvozené třídy v JavaScriptu používáme klíčové slovo `extends`. Zde je příklad, kdy dědíme ze třídy `Dog`:
class Rottweiler extends Dog {
constructor(name, age) {
super(name, age);
this.breed = 'rottweiler';
}
}
Jak vidíte, třída je z velké části stejná jako dříve. Uvnitř konstruktoru jsme ale zavolali funkci `super`. Klíčové slovo `super` odkazuje na konstruktor základní třídy. Proto v naší odvozené třídě voláme konstruktor základní třídy a předáváme jméno a věk.
const myPet = new Rottweiler();
console.log(myPet);
Závěr
V tomto článku jsme si podrobně vysvětlili koncept tříd v JavaScriptu. Popsali jsme, co třídy jsou, jaké členy mohou obsahovat a jaké jsou různé klasifikace členů. Vše jsme si pak ukázali na praktických příkladech.
Pokud se chcete dozvědět více, doporučujeme si přečíst otázky týkající se objektově orientovaného programování, které se často objevují u pracovních pohovorů.