JavaScript používá prototypovou dědičnost: každý objekt dědí vlastnosti a metody ze svého prototypového objektu.
tradiční třída jako plán pro vytváření objektů, používaných v jazycích jako Java nebo Swift, neexistuje v JavaScriptu. Prototypové dědictví se zabývá pouze objekty.
prototypová dědičnost může napodobit Klasické dědictví třídy. Aby tradiční třídy JavaScript, ES2015 standard zavádí class
syntax: syntaktický cukr nad prototypal dědictví.,
tento příspěvek vás seznámí s třídami JavaScriptu: jak definovat třídu, inicializovat instanci, Definovat pole a metody, porozumět soukromým a veřejným polím, pochopit statická pole a metody.
1. Definice: třídy klíčové slovo
speciální klíčové slovo class
definuje třídu v Javascriptu:
class User { // The body of class}
výše uvedený kód definuje třídu User
. Kudrnaté závorky { }
vymezují tělo třídy. Všimněte si, že tato syntaxe je pojmenována třídní deklarace.,
nejste povinni uvést název třídy. Pomocí třídy výrazu lze přiřadit třídu do proměnné:
const UserClass = class { // The body of class};
můžete snadno exportovat třídy jako součást ES2015 modul. Zde je syntaxe pro standardní export:
export default class User { // The body of class}
A jménem export:
export class User { // The body of class}
třídy se stává užitečné, když vytvoříte instanci třídy. Instance je objekt obsahující data a chování popsané třídou.,
new
provozovatel vytvoří instanci třídy v Javascriptu: instance = new Class()
.
například, můžete vytvořit instanci User
class pomocí prvku new
operátor:
const myUser = new User();
new User()
vytvoří instanci User
třídy.
2. Inicializace: konstruktor()
constructor(param1, param2, ...)
je speciální metody v těle třídy, která inicializuje instanci., To je místo, kde nastavíte počáteční hodnoty polí nebo provedete jakýkoli druh nastavení objektu.
V následujícím příkladu konstruktor nastaví počáteční hodnotu pole name
:
class User { constructor(name) { this.name = name; }}
User
‚s konstruktor má jeden parametr name
, který se používá k nastavení počáteční hodnoty pole this.name
.
uvnitř konstruktoru this
hodnota se rovná nově vytvořené instanci.,
argumenty používá k vytvoření instance třídy se stal parametry konstruktoru:
class User { constructor(name) { name; // => 'Jon Snow' this.name = name; }}const user = new User('Jon Snow');
name
parametr v konstruktoru má hodnotu 'Jon Snow'
.
Pokud pro třídu nedefinujete Konstruktor, vytvoří se výchozí. Výchozí konstruktor je prázdná funkce, která nemění instanci.
současně může mít Třída JavaScript až jeden Konstruktor.
3. Pole
pole třídy jsou proměnné, které obsahují informace., Pole mohou být připojeny až 2 subjekty:
- Pole na instanci třídy
- Pole, na třídě sám (neboli statická)
pole mají také 2 úrovně dostupnosti:
- Public: pole je přístupné kdekoliv
- Soukromé: pole je přístupné pouze v rámci těla třídy
3.1 Veřejné instance pole
podívejme se znovu na předchozí fragment kódu:
class User { constructor(name) { this.name = name; }}
výraz this.name = name
vytvoří instanci pole name
a přiřadí počáteční hodnota.,
Později můžete přístup name
pole pomocí accessor vlastnost:
const user = new User('Jon Snow');user.name; // => 'Jon Snow'
name
je veřejná pole, protože můžete přistupovat mimo User
class těla.
když jsou pole vytvořena implicitně uvnitř konstruktoru, jako v předchozím scénáři, mohlo by být obtížné pochopit seznam polí. Musíte je dešifrovat z kódu konstruktoru.
lepším přístupem je explicitně deklarovat pole třídy., Bez ohledu na to, co Konstruktor dělá, instance má vždy stejnou sadu polí.
návrh třídních polí umožňuje definovat pole uvnitř těla třídy. Plus, můžete uvést počáteční hodnotu hned:
class SomeClass { field1; field2 = 'Initial value'; // ...}
změnit na User
class a vyhlásit veřejné pole name
:
class User { name; constructor(name) { this.name = name; }}const user = new User('Jon Snow');user.name; // => 'Jon Snow'
name;
uvnitř těla třídy deklaruje veřejné pole name
.,
veřejná pole deklarovaná takovým způsobem jsou expresivní: rychlý pohled na pole stačí k pochopení datové struktury třídy.
pole třídy může být navíc inicializováno hned na deklaraci.
class User { name = 'Unknown'; constructor() { // No initialization }}const user = new User();user.name; // => 'Unknown'
name = 'Unknown'
uvnitř třídy tělo deklaruje pole name
a inicializuje ji s hodnotou 'Unknown'
.
neexistuje žádné omezení přístupu nebo aktualizace veřejných polí., Hodnoty můžete číst a přiřadit veřejným polím uvnitř konstruktoru, metod a mimo třídu.
3.2 Private instance fields
zapouzdření je důležitý koncept, který vám umožní skrýt vnitřní detaily třídy. Někdo, kdo používá zapouzdřenou třídu, závisí pouze na veřejném rozhraní, které třída poskytuje, a nespojuje se s podrobnostmi o implementaci třídy.
třídy organizované s ohledem na zapouzdření se při změně podrobností implementace snadněji aktualizují.,
dobrým způsobem, jak skrýt interní data objektu, je použití soukromých polí. Jedná se o pole, která lze číst a měnit pouze v rámci třídy, do které patří. Vnější svět třídy nemůže přímo měnit soukromá pole.
soukromá pole jsou přístupná pouze v těle třídy.
Prefix název pole se zvláštním symbolem#
aby byl soukromý, např.#myField
., Předpona #
musí být uchována při každé práci s polem: deklarovat, přečíst nebo upravit.
Pojďme se ujistit, že pole #name
lze nastavit jednou, při inicializaci instance:
#name
je privátní oblasti. Můžete přistupovat a upravovat #name
v těle User
. Metoda getName()
(více o metodách v další části) má přístup k soukromému poli #name
.,
Ale pokud se pokusíte o přístup k soukromé oblasti #name
User
class těla, syntaktická chyba, je vyvolána: SyntaxError: Private field '#name' must be declared in an enclosing class
.
3.3 veřejná statická pole
můžete také definovat pole na samotné třídě: statická pole. Ty jsou užitečné pro definování třídních konstant nebo ukládání informací specifických pro danou třídu.
Chcete-li vytvořit statické pole v JavaScript třídy, používat speciální klíčové slovo static
následuje název pole: static myStaticField
.,
přidáme nové pole type
, které označuje typ uživatele: admin nebo regular. Statické pole TYPE_ADMIN
TYPE_REGULAR
jsou užitečné konstanty rozlišit typy uživatelů:
static TYPE_ADMIN
static TYPE_REGULAR
definovat statické proměnné uvnitř User
třídy. Pro přístup ke statickým polím musíte použít třídu následovanou názvem pole: User.TYPE_ADMIN
a .
3.,4 Private static fields
někdy jsou i statická pole implementačním detailem, který chcete skrýt. V tomto ohledu můžete statické pole soukromé.
aby statické pole bylo soukromé, Předpona názvu pole s #
speciální symbol: static #myPrivateStaticField
.
Řekněme, že byste chtěli omezit počet instancí třídy User
., Skrýt údaje o případy omezení, můžete vytvořit soukromou statického pole:
statické pole User.#MAX_INSTANCES
nastaví maximální počet povolených instancí, zatímco User.#instances
statické pole se počítá skutečný počet instancí.
tato soukromá statická pole jsou přístupná pouze ve třídě User
. Nic z vnějšího světa nemůže zasahovat do mechanismu limitů: to je výhoda zapouzdření.
4. Metody
pole obsahují data., Schopnost měnit data se však provádí speciálními funkcemi, které jsou součástí třídy: metody.
třídy JavaScriptu podporují instance i statické metody.
4.1 Instance methods
Instance methods can access and modify instance data. Metody Instance mohou volat jiné metody instance, stejně jako jakoukoli statickou metodu.,
například, pojďme se definovat metodu getName()
, která vrátí jméno v User
třídy:
Ve třídě metoda, stejně jako v konstruktoru, this
hodnota je rovna instanci třídy. Používání this
pro přístup k data instance: this.field
, nebo dokonce volat jiné metody: this.method()
.,
Pojďme přidat novou metodu nameContains(str)
, který má jeden parametr a volá jinou metodu:
nameContains(str) { ... }
je metoda User
třída, která přijímá jeden parametr str
. Více než to, že provede jinou metodu instance this.getName()
získat jméno uživatele.
metoda může být také soukromá. Chcete-li metodu private prefix její název s #
.
getName()
metoda private:
#getName()
je privátní metoda., Uvnitř metody nameContains(str)
voláte soukromou metodu takto: this.#getName()
.
být soukromý, #getName()
nelze volat mimoUser
tělo třídy.
4.2 getry a settery
getter a setter napodobují pravidelné pole, ale s větší kontrolou toho, jak je pole přístupné a změněno.
getter se provádí při pokusu o získání hodnoty pole, zatímco setter při pokusu o nastavení hodnoty.,
ujistěte Se, že name
vlastnost User
nemůže být prázdný, pojďme zabalit soukromé pole #nameValue
getter a setter:
get name() {...}
getter je proveden, když máte přístup k hodnotě pole: user.name
.
4.3 statické metody
statické metody jsou Funkce připojené přímo ke třídě. Mají logiku související s třídou, spíše než s instancí třídy.,
pro vytvoření statické metody použijte speciální klíčové slovo static
následované syntaxí pravidelné metody: static myStaticMethod() { ... }
.
Při práci s statické metody, existují 2 jednoduchá pravidla na paměti:
- statická metoda může přístup statického pole
- statické metody nelze získat přístup k instanci pole.
například vytvoříme statickou metodu, která detekuje, zda již byl uživatel s určitým názvem přijat.,
isNameTaken()
je statická metoda, která používá statické soukromé pole User.#takenNames
zkontrolujte, zda přijatá jména.
5. Dědičnost: rozšiřuje
třídy v JavaScriptu podporují jediné dědictví pomocí klíčového slova extends
.
Ve výrazu class Child extends Parent { }
Child
třída dědí z Parent
konstruktoru, polí a metod.
například vytvoříme novou dětskou třídu ContentWriter
, která rozšiřuje nadřazenou třídu User
.,
ContentWriter
dědí od User
konstruktoru, metodu getName()
pole name
. Také třída ContentWriter
deklaruje nové pole posts
.
všimněte si, že soukromí členové rodičovské třídy nejsou zděděni dětskou třídou.
5.1 Rodič konstruktor: super() v konstruktoru()
Pokud byste chtěli volat parent konstruktoru u dítěte třídy, musíte použít super()
speciální funkce k dispozici v dítě konstruktor.,
řekněme například, ContentWriter
konstruktoru volání nadřazeného konstruktoru User
, stejně jako inicializovat příspěvky pole:
super(name)
dítě uvnitř třídy ContentWriter
spustí konstruktor nadřazené třídy User
.
Všimněte si, že uvnitř konstruktoru dítěte musíte provést super()
před použitím Klíčové slovo. Volání super()
zajišťuje, že Nadřazený Konstruktor inicializuje instanci.,
class Child extends Parent { constructor(value1, value2) { // Does not work! this.prop2 = value2; super(value1); }}
5.2 Rodič stupně: super v metodách
Pokud byste chtěli, aby přístup k mateřské metoda uvnitř dítěte metodu, můžete použít speciální klávesová zkratka super
.
getName()
dítěte class ContentWriter
přistupuje metoda super.getName()
přímo z nadřazené třídy User
.
tato funkce se nazývá metoda přepsání.
Všimněte si ,že můžete použítsuper
se statickými metodami také pro přístup k statickým metodám rodiče.
6., Object type checking: instanceof
object instanceof Class
is the operator that determines if object
is an instance of Class
.
Let’s see instanceof
operator in action:
user
is an instance of User
class, user instanceof User
evaluates to true
.
The empty object {}
is not an instance of User
, correspondingly obj instanceof User
is false
.,
instanceof
je polymorfní: operátor detekuje dítě jako instanci mateřské třídy.
writer
je instance dětské třídy ContentWriter
. Operátor writer instanceof ContentWriter
vyhodnotí true
.
současně ContentWriter
je dítě třídu User
. Takže writer instanceof User
vyhodnocuje na true
stejně.
Co když chcete určit přesnou třídu instance?, Můžete použít vlastnost constructor
a porovnat přímo s třídou:
writer.constructor === ContentWriter; // => truewriter.constructor === User; // => false
7. Třídy a prototypy
musím říci, že syntaxe třídy v JavaScriptu odvádí skvělou práci pro abstrakci z prototypové dědičnosti. Pro popis syntaxe class
jsem termín prototyp ani nepoužil.
ale třídy jsou postaveny na vrcholu prototypové dědičnosti. Každá třída je funkce a vytváří instanci, když je vyvolána jako konstruktor.
následující dva úryvky kódu jsou ekvivalentní.,
Verze třídy:
verze používající prototyp:
syntaxe třídy je mnohem jednodušší, pokud znáte klasický dědičný mechanismus jazyků Java nebo Swift.
každopádně, i když používáte syntaxi třídy v JavaScriptu, doporučuji vám mít dobrý přehled o prototypové dědičnosti.
8. Funkce třídy dostupnost
funkce třídy uvedené v tomto příspěvku jsou rozloženy na ES2015 a návrhy ve fázi 3.,
Na konci roku 2019, třídy, funkce jsou rozděleny mezi:
- Veřejné a soukromé instance pole jsou součástí Třídy oblastech návrhu
- Soukromé instance, metody a přístupové objekty jsou součástí Třídy soukromé metody návrhu
- Veřejné a soukromé statické pole a soukromé statické metody jsou součástí Třídy statické vlastnosti návrhu
- zbytek je součástí standardu ES2015.
9. Závěr
třídy JavaScriptu inicializují instance pomocí konstruktorů, definují pole a metody., Pole a metody můžete připojit i na samotnou třídu pomocí klíčového slova static
.
dědičnost je dosažena pomocíextends
Klíčové slovo: můžete snadno vytvořit dětskou třídu od rodiče. super
Klíčové slovo se používá pro přístup k mateřské třídě z dětské třídy.
Chcete-li využít zapouzdření, vytvořte pole a metody soukromé, abyste skryli vnitřní podrobnosti svých tříd. Soukromá pole a názvy metod musí začínat #
.,
třídy v JavaScriptu se stávají stále pohodlnějšími.
Co si myslíte o použití#
na prefix private properties?