JavaScript folosește moștenirea prototipică: fiecare obiect moștenește proprietăți și metode din obiectul său prototip.

clasa tradițională ca model pentru a crea obiecte, utilizate în limbi precum Java sau Swift, nu există în JavaScript. Moștenirea prototipică se ocupă numai de obiecte. moștenirea prototipică poate emula moștenirea clasică a clasei. Pentru a aduce clasele tradiționale în JavaScript, standardul ES2015 introduce sintaxaclass: un zahăr sintactic peste moștenirea prototipică.,

această postare vă familiarizează cu clasele JavaScript: cum să definiți o clasă, să inițializați instanța, să definiți câmpuri și metode, să înțelegeți câmpurile private și publice, să înțelegeți câmpurile și metodele statice.

1. Definiție: clasa de cuvinte cheie

special de cuvinte cheie class definește o clasă în JavaScript:

class User { // The body of class}

codul De mai sus definește o clasă User. Bretelele ondulate{ } delimitează corpul clasei. Rețineți că această sintaxă este numită declarație de clasă.,

nu sunteți obligat să indicați numele clasei. Folosind o expresie de clasă puteți atribui clasa unei variabile:

const UserClass = class { // The body of class};

puteți exporta cu ușurință o clasă ca parte a unui modul ES2015. Iata sintaxa pentru o implicit export:

export default class User { // The body of class}

Și un nume de export:

export class User { // The body of class}

clasa devine util atunci când creați o instanță a clasei. O instanță este un obiect care conține date și comportament descrise de clasă.,

new operator instanțiază clasa în JavaScript: instance = new Class().

De exemplu, poti instantia User clasa folosind new operator:

const myUser = new User();

new User() creează o instanță a User clasa.

2. Inițializare: constructor ()

constructor(param1, param2, ...) este o metodă specială în corpul unei clase care inițializează instanța., Acesta este locul în care setați valorile inițiale pentru câmpuri sau faceți orice fel de configurare a obiectului.

În exemplul următor constructorul stabilește valoarea inițială a câmpului name:

class User { constructor(name) { this.name = name; }}

User‘s constructorul are un singur parametru name, care este folosit pentru a seta valoarea inițială a câmpului this.name.

în interiorul constructorului this valoarea este egală cu instanța nou creată.,

argumentele folosite pentru a instantia clasa a deveni parametri de constructor:

class User { constructor(name) { name; // => 'Jon Snow' this.name = name; }}const user = new User('Jon Snow');

name parametru în constructor are valoarea 'Jon Snow'.

dacă nu definiți un constructor pentru clasă, se creează unul implicit. Constructorul implicit este o funcție goală, care nu modifică instanța. în același timp, o clasă JavaScript poate avea până la un constructor.

3. Câmpuri

câmpurile de clasă sunt variabile care conțin informații., Câmpurile pot fi atașate la 2 entități:

  1. Domenii în instanță de clasă
  2. Domenii pe clasă în sine (aka static)

domeniile, de asemenea, au 2 nivele de accesibilitate:

  1. Public: domeniul este accesibil de oriunde,
  2. Privat: domeniul este accesibil doar în corpul de clasa

3.1 Publice exemplu de domenii

Să ne uităm din nou la ultimul fragment de cod:

class User { constructor(name) { this.name = name; }}

expresia this.name = name creează o instanță domeniu name și atribuie o valoare inițială.,

mai Târziu, puteți accesa name folosind un câmp de proprietate accesor:

const user = new User('Jon Snow');user.name; // => 'Jon Snow'

name este un domeniu public, deoarece puteți accesa în afara User clasa a corpului.

când câmpurile sunt create implicit în interiorul constructorului, ca în scenariul anterior, ar putea fi dificil să înțelegeți lista câmpurilor. Trebuie să le descifrați din Codul constructorului.

o abordare mai bună este de a declara în mod explicit câmpurile de clasă., Indiferent de constructor, instanța are întotdeauna același set de câmpuri.

propunerea class fields vă permite să definiți câmpurile din interiorul corpului clasei. În Plus, puteți indica valoarea inițială imediat:

class SomeClass { field1; field2 = 'Initial value'; // ...}

Să modificați User clasa și a declara un domeniu public name:

class User { name; constructor(name) { this.name = name; }}const user = new User('Jon Snow');user.name; // => 'Jon Snow'

name; în interiorul corpului de clasa declară un domeniu public name.,

câmpurile publice declarate astfel sunt expresive: o privire rapidă asupra declarațiilor câmpurilor este suficientă pentru a înțelege structura de date a clasei.

Mai mult, câmpul de clasă poate fi inițializat imediat la declarație.

class User { name = 'Unknown'; constructor() { // No initialization }}const user = new User();user.name; // => 'Unknown'

name = 'Unknown' în interiorul clasei corpul declară un câmp name și inițializează cu valoarea 'Unknown'.

nu există nicio restricție privind accesul sau actualizarea câmpurilor publice., Puteți citi și atribui valori câmpurilor publice din interiorul constructorului, metodelor și în afara clasei.

3.2 câmpuri private de instanță

încapsularea este un concept important care vă permite să ascundeți detaliile interne ale unei clase. Cineva care folosește o clasă încapsulată depinde numai de interfața publică pe care o oferă clasa și nu se cuplează la detaliile de implementare ale clasei.

clasele organizate având în vedere încapsularea sunt mai ușor de actualizat atunci când detaliile implementării se schimbă., o modalitate bună de a ascunde datele interne ale unui obiect este utilizarea câmpurilor private. Acestea sunt câmpurile care pot fi citite și modificate numai în cadrul clasei din care fac parte. Lumea exterioară a clasei nu poate schimba direct câmpurile private.

câmpurile private sunt accesibile numai în corpul clasei.

Prefix numele câmpului cu simbolul special # pentru a face privat, de exemplu #myField., Prefixul # trebuie păstrat de fiecare dată când lucrați cu câmpul: declarați-l, citiți-l sau modificați-l.

Să asigurați-vă că domeniul #name poate fi setat o dată la exemplu de inițializare:

#name este un teren privat. Puteți accesa și modifica #name în corpul User. Metoda getName() (mai multe despre metode în secțiunea următoare) pot accesa domeniul privat #name.,

Dar dacă încercați să accesați domeniul privat #name in afara de User clasa a corpului, o eroare de sintaxă este aruncat: SyntaxError: Private field '#name' must be declared in an enclosing class.

3.3 câmpuri statice publice

de asemenea, puteți defini câmpuri pe clasa în sine: câmpurile statice. Acestea sunt utile pentru a defini constante de clasă sau stoca informații specifice clasei.

Pentru a crea câmpuri statice într-un JavaScript clasă, utilizarea unor cuvinte cheie static urmat de numele câmpului: static myStaticField.,

să adăugăm un câmp nou type care indică tipul de utilizator: admin sau regular. În câmpuri statice TYPE_ADMIN și TYPE_REGULAR sunt la îndemână constante de a diferenția tipurile de utilizatori:

static TYPE_ADMIN și static TYPE_REGULAR defini variabile statice în interiorul User clasa. Pentru a accesa câmpurile statice, trebuie să utilizați class urmat de numele câmpului: User.TYPE_ADMIN și User.TYPE_REGULAR.

3.,4 câmpuri statice private

uneori, chiar și câmpurile statice sunt un detaliu de implementare pe care doriți să îl ascundeți. În acest sens, puteți face câmpurile statice private.

Pentru a face static domeniul privat, prefix numele câmpului cu # simbol special: static #myPrivateStaticField.

Să presupunem că doriți să limitați numărul de instanțe ale clasei User., Pentru a ascunde detaliile despre cazuri limitele, puteți crea privată câmpuri statice:

câmp static User.#MAX_INSTANCES setează numărul maxim de permise de cazuri, în timp ce User.#instances câmp static contează numărul real de cazuri.

aceste câmpuri statice private sunt accesibile numai în clasa User. Nimic din lumea exterioară nu poate interfera cu mecanismul limitelor: acesta este beneficiul încapsulării.

4. Metode

câmpurile dețin date., Dar capacitatea de a modifica datele este realizată prin funcții speciale care fac parte din clasă: metodele.

clasele JavaScript acceptă atât metode de instanță, cât și metode statice.

4.1 metode de instanță

metodele de instanță pot accesa și modifica datele de instanță. Metodele de instanță pot apela alte metode de instanță, precum și orice metodă statică.,

De exemplu, haideți să definim o metodă getName() care returnează numele în User clasa:

Intr-o metoda a clasei, precum și în constructor, this valoare egal la instanță de clasă. Folosiți this pentru a accesa date exemplu: this.field, sau chiar apela alte metode: this.method().,

Să adăugați o nouă metodă nameContains(str) care are un singur parametru și solicită o altă metodă:

nameContains(str) { ... } este o metodă de User clasa care acceptă un parametru str. Mai mult decât atât, execută o altă metodă a instanței this.getName() pentru a obține numele utilizatorului.

o metodă poate fi, de asemenea, privată. Pentru a face metoda prefix privat numele său cu #.

Să facem getName() method:

#getName() este o metodă privat., În interiorul metodei nameContains(str) apelați o metodă privată astfel: this.#getName().

Fiind privat, #getName() nu poate fi numit din afara User clasa a corpului.

4.2 Getters și setters

getter și setter mimează câmpul regulat, dar cu mai mult control asupra modului în care este accesat și schimbat câmpul.

getter este executat pe o încercare de a obține valoarea câmpului, în timp ce setter pe o încercare de a seta o valoare.,

Pentru a vă asigura că name proprietatea User nu poate fi gol, hai să terminăm domeniul privat #nameValue într-un getter și setter:

get name() {...} getter este executat atunci când accesați valoarea câmpului: user.name.

4.3 metode statice

metodele statice sunt funcții atașate direct clasei. Ei dețin logica legate de clasa, mai degrabă decât la instanța clasei.,

Pentru a crea o metodă statică speciale de utilizare de cuvinte cheie static urmată de o metodă obișnuită sintaxa: static myStaticMethod() { ... }.când lucrați cu metode statice, există 2 Reguli simple de reținut:

  1. o metodă statică poate accesa câmpuri statice
  2. o metodă statică nu poate accesa câmpuri de instanță.

de exemplu, să creăm o metodă statică care detectează dacă un utilizator cu un anumit nume a fost deja luat.,

isNameTaken() este o metodă statică care utilizează câmp privat static User.#takenNames pentru a verifica pentru luat numele.

5. Moștenire: extinde

clasele din JavaScript acceptă o singură moștenire folosind cuvântul cheieextends.

În expresia class Child extends Parent { } Child clasa moștenește de la Parent constructorul, câmpuri și metode.

De exemplu, să creeze un nou copil de clasa ContentWriter care extinde clasa părinte User.,

ContentWriter moștenește de la User constructorul, metoda getName() iar câmpul name. De asemenea, clasa ContentWriter declară un câmp nou posts. rețineți că membrii privați ai unei clase părinte nu sunt moșteniți de clasa copil.

5.1 constructor părinte: super () în constructor ()

Dacă doriți să apelați constructorul părinte într-o clasă copil, trebuie să utilizați funcția specială super() disponibilă în constructorul copil.,

De exemplu, să facem ContentWriter apel constructor părinte constructor de User, precum și inițializa posturi domeniu:

super(name) în clasa copil ContentWriter execută constructorul din clasa părinte User.

Rețineți că în interiorul copilului constructorul trebuie să execute super() înainte de a utiliza this cuvinte cheie. Apelarea super() asigură că constructorul părinte inițializează instanța.,

class Child extends Parent { constructor(value1, value2) { // Does not work! this.prop2 = value2; super(value1); }}

5.2 Părinte exemplu: super în metode

Dacă doriți pentru a accesa părinte metodă în interiorul unui copil metodă, puteți utiliza speciale de comenzi rapide super.

getName() de copil de clasa ContentWriter acceseaza metoda super.getName() direct de la clasa părinte User.

această caracteristică se numește metodă imperativă.

rețineți că puteți utilizasuper și cu metode statice, pentru a accesa metodele statice ale părintelui.

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 este polimorf: operatorul detectează un copil ca o instanță a clasei părinte.

writer este o instanță a clasei copil ContentWriter. Operatorul writer instanceof ContentWriter evaluează la true.

în același timp ContentWriter este o clasă copil de User. Deci writer instanceof Userevaluează latrue de asemenea. ce se întâmplă dacă doriți să determinați clasa exactă a instanței?, Puteți folosi constructor proprietate și compara direct cu clasa:

writer.constructor === ContentWriter; // => truewriter.constructor === User; // => false

7. Clase și prototipuri

trebuie să spun că sintaxa clasei în JavaScript face o treabă excelentă de abstractizat din moștenirea prototipică. Pentru a descrie sintaxa class nu am folosit nici măcar termenul prototip.

dar clasele sunt construite pe partea de sus a moștenirii prototip. Fiecare clasă este o funcție și creează o instanță atunci când este invocată ca constructor. următoarele două fragmente de cod sunt echivalente.,

Versiunea clasei:

Versiunea care utilizează prototipul:

sintaxa clasei este mult mai ușor de lucrat dacă sunteți familiarizat cu mecanismul clasic de moștenire al Limbilor Java sau Swift.

oricum, chiar dacă utilizați sintaxa clasei în JavaScript, vă recomand să aveți o bună înțelegere a moștenirii prototipice.

8. Caracteristicile clasei disponibile

caracteristicile clasei prezentate în această postare sunt distribuite în ES2015 și propuneri în etapa 3.,

La sfârșitul anului 2019, caracteristici de clasă sunt împărțite între:

  • Public și privat exemplu domenii fac parte din Clasa domenii propunere
  • Privat exemplu metode și evaluatorilor sunt parte din Clasa privat metode propunere
  • Public și privat câmpuri statice și private metode statice sunt parte din Clasa static caracteristici propunere
  • restul este parte a ES2015 standard.

9. Concluzie

clasele JavaScript inițializează instanțele cu Constructori, definesc câmpuri și metode., Puteți atașa câmpuri și metode chiar și pe clasa în sine folosind cuvântul cheie static.

moștenirea se realizează folosind extends cuvânt cheie: puteți crea cu ușurință o clasă copil de la un părinte. super cuvântul cheie este utilizat pentru a accesa clasa părinte dintr-o clasă copil. pentru a profita de încapsulare, faceți câmpurile și metodele private pentru a ascunde detaliile interne ale claselor dvs. Numele câmpurilor și metodelor private trebuie să înceapă cu #.,

clasele din JavaScript devin din ce în ce mai convenabile de utilizat.

Ce părere aveți despre utilizarea # pentru prefixarea proprietăților private?