JavaScript bruger prototypearv: hvert objekt arver egenskaber og metoder fra dets prototypeobjekt.

den traditionelle klasse som blueprint til at oprette objekter, der bruges på sprog som Java eller S .ift, findes ikke i JavaScript. Den prototypiske arv handler kun om objekter.

den prototypiske arv kan efterligne den klassiske klassearv. For at bringe de traditionelle klasser til JavaScript introducerer ES2015-standarden class syntaks: et syntaktisk sukker over den prototype arv.,

dette indlæg gør dig bekendt med JavaScript-klasser: hvordan man definerer en klasse, initialiserer forekomsten, definerer felter og metoder, forstår de private og offentlige felter, forstår de statiske felter og metoder.

1. Definition: klasse søgeord

De særlige søgeord class definerer en klasse i JavaScript:

class User { // The body of class}

koden ovenfor definerer en klasse User. De krøllede seler { } afgræns klassekroppen. Bemærk, at denne syntaks hedder klassedeklaration.,

du er ikke forpligtet til at angive klassenavnet. Ved at bruge et klasseudtryk kan du tildele klassen til en variabel:

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

Du kan nemt eksportere en klasse som en del af et ES2015-modul. Her er syntaksen for en standard udførsel:

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

Og en navngiven eksport:

export class User { // The body of class}

Den klasse bliver nyttigt, når du opretter en instans af klassen. En instans er et objekt, der indeholder data og adfærd beskrevet af klassen.,

new operatør eksemplificerer den klasse i JavaScript: instance = new Class().

For eksempel, du kan instantiere User class hjælp new bruger:

const myUser = new User();

new User() opretter en instans af User class.

2. Initialisering: konstruktør()

constructor(param1, param2, ...) er en særlig metode i kroppen af en klasse, der initialiserer eksempel., Det er det sted, hvor du indstiller de oprindelige værdier for felterne, eller gør nogen form for objektopsætning.

I det følgende eksempel konstruktøren sætter den oprindelige værdi af feltet name:

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

User‘s constructor har en parameter name som bruges til at indstille den første værdi i feltet this.name.

inde i konstruktøren this værdi er lig med den nyoprettede forekomst.,

De argumenter, der bruges til at instantiere klassen blive parametre i konstruktøren:

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

name parameter inde i constructor har værdi 'Jon Snow'.

Hvis du ikke definerer en konstruktør for klassen, oprettes en standard en. Standardkonstruktøren er en tom funktion, som ikke ændrer forekomsten.

samtidig kan en JavaScript-klasse have op til en konstruktør.

3. Felter

Klassefelter er variabler, der indeholder oplysninger., Felter, der kan være knyttet til 2 enheder:

  1. Felter på klasse-eksempel
  2. Felter på klassen selv (aka statisk)

De felter, der også har 2 niveauer af adgang:

  1. Public: området er tilgængeligt overalt
  2. Privat: feltet er kun tilgængelige i kroppen af klassen

3.1 Offentlig instans felter

Lad os igen se på den tidligere kodestykke:

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

udtrykket this.name = name opretter en instans felt name og tildeler det en initial værdi.,

Senere du kan få adgang name felt ved hjælp af en ejendom accessor:

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

name er et forbudt område, fordi du kan få adgang til det uden for User class kroppen.

Når felterne oprettes implicit inde i konstruktøren, som i det foregående scenario, kan det være svært at forstå felterne listen. Du skal dechiffrere dem fra konstruktørens kode.

en bedre tilgang er eksplicit at erklære klassefelterne., Uanset hvad konstruktør gør, har forekomsten altid det samme sæt felter.

forslaget om klassefelter giver dig mulighed for at definere felterne inde i klassens krop. Plus, kan du angive den oprindelige værdi lige med det samme:

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

Lad os ændre User class og erklærer, at et offentligt felt name:

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

name; inde i kroppen af klasse erklærer et offentligt felt name.,

de offentlige felter, der er erklæret sådan, er udtryksfulde: et hurtigt kig på felterne erklæringer er nok til at forstå klassens datastruktur.

desuden kan klassefeltet initialiseres med det samme ved erklæring.

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

name = 'Unknown' i klasse krop erklærer et felt name og initialiserer det med værdi 'Unknown'.

Der er ingen begrænsninger for adgang eller opdatering af de offentlige felter., Du kan læse og tildele værdier til offentlige felter inde i konstruktøren, metoder og uden for klassen.

3.2 Private forekomstfelter

indkapsling er et vigtigt begreb, der lader dig skjule de interne detaljer i en klasse. En person, der bruger en indkapslet klasse, afhænger kun af den offentlige grænseflade, som klassen leverer, og parrer ikke til implementeringsoplysningerne for klassen.

klasser organiseret med indkapsling i tankerne er lettere at opdatere, når implementeringsdetaljerne ændres.,

en god måde at skjule interne data på et objekt er at bruge de private felter. Dette er de felter, der kun kan læses og ændres inden for den klasse, de tilhører. Klassens omverden kan ikke ændre private felter direkte.

de private felter er kun tilgængelige inden for klassens krop.

præfiks feltnavnet med det specielle symbol #for at gøre det privat, f.eks. #myField., Præfikset # skal opbevares hver gang du arbejder med feltet: erklære det, læse det eller ændre det.

Lad os sørge for, at feltet #name kan sættes gang i eksempel initialisering:

#name er et privat område. Du kan få adgang til og ændre #name i kroppen af User. Metoden getName() (mere om metoder i næste afsnit) kan få adgang til det private område #name.,

Men hvis du forsøger at få adgang til det private område #name uden for User class krop, en syntaks fejl er smidt: SyntaxError: Private field '#name' must be declared in an enclosing class.

3.3 offentlige statiske felter

Du kan også definere felter på selve klassen: de statiske felter. Disse er nyttige til at definere klassekonstanter eller gemme oplysninger, der er specifikke for klassen.

for at oprette statiske felter i en JavaScript-klasse skal du bruge det specielle søgeord staticefterfulgt af feltnavnet: static myStaticField.,

lad os tilføje et nyt felt type der angiver brugertype: admin eller almindelig. Den statiske felter TYPE_ADMIN og TYPE_REGULAR er handy konstanter til at differentiere brugeren typer:

static TYPE_ADMIN og static TYPE_REGULAR definere statiske variabler inde i User class. For at få adgang til de statiske felter skal du bruge klassen efterfulgt af feltnavnet: User.TYPE_ADMIN og User.TYPE_REGULAR.

3.,4 Private statiske felter

Nogle gange er selv de statiske felter en implementeringsdetalje, som du gerne vil skjule. I denne henseende kan du gøre statiske felter private.

for at gøre det statiske felt privat, præfiks feltnavnet med #specielt symbol: static #myPrivateStaticField.

lad os sige, at du gerne vil begrænse antallet af forekomster af User klassen., For at skjule oplysninger om forekomster grænser, kan du oprette den private statiske felter:

Den statiske felt User.#MAX_INSTANCES sætter det maksimale antal tilladte forekomster, mens User.#instances statisk felt, tæller den faktiske antal tilfælde.

disse private statiske felter er kun tilgængelige inden for User klassen. Intet fra den eksterne verden kan forstyrre grænsemekanismen: det er fordelen ved indkapsling.

4. Metoder

felterne indeholder data., Men evnen til at ændre data udføres af specielle funktioner, der er en del af klassen: metoderne.

JavaScript-klasserne understøtter både forekomst og statiske metoder.

4.1 Instansmetoder

Instansmetoder kan få adgang til og ændre instansdata. Instansmetoder kan kalde andre instansmetoder såvel som enhver statisk metode.,

For eksempel, lad os definere en metode getName(), der returnerer navnet i User class:

I en klasse-metode, samt i konstruktøren, this værdi svarer til klasse f.eks. Brug this for at få adgang eksempel data: this.field, eller endda ringe til andre metoder: this.method().,

Lad os tilføje en ny metode nameContains(str), der har en parameter, og kalder en anden metode:

nameContains(str) { ... } er en metode til User class, der accepterer en parameter str. Mere end det udfører den en anden metode af forekomsten this.getName() for at få brugerens navn.

en metode kan også være privat. For at gøre metoden privat præfiks sit navn med #.

Lad os gøre getName() metode privat:

#getName() er en privat metode., Inde i metoden nameContains(str) du kalder en privat metode på denne måde: this.#getName().

Er det private, #getName() kan ikke kaldes uden for User class kroppen.

4.2 Getters og setters

getter og setter efterligner regelmæssigt felt, men med mere kontrol over, hvordan feltet åbnes og ændres.

getter udføres på et forsøg på at få feltværdien, mens setter på et forsøg på at indstille en værdi.,

sørg for, At name ejet af User kan være tom, lad os afslutte den private område #nameValue i en getter og setter:

get name() {...} getter er udført, når du får adgang til værdien af feltet: user.name.

4.3 statiske metoder

de statiske metoder er funktioner, der er knyttet direkte til klassen. De holder logik relateret til klassen, snarere end til forekomsten af klassen.,

for at oprette en statisk metode skal du bruge det specielle søgeord staticefterfulgt af en almindelig metodesynta.: static myStaticMethod() { ... }.

Når du arbejder med statiske metoder, der er 2 simple regler at huske:

  1. En statisk metode kan få adgang til de statiske felter
  2. En statisk metode kan ikke adgang eksempel felter.

lad os for eksempel oprette en statisk metode, der registrerer, om en bruger med et specifikt navn allerede er taget.,

isNameTaken() er en statisk metode, der bruger det statiske private felt User.#takenNames for at kontrollere for taget navne.

5. Arv: udvider

klasserne i JavaScript understøtter enkelt arv ved hjælp afextends nøgleord.

I udtrykket class Child extends Parent { } Child klasse arver fra Parent konstruktøren, felter og metoder.

lad os for eksempel oprette en ny børneklasse ContentWriter, der udvider forældreklassenUser.,

ContentWriter arver fra User konstruktøren, den metode getName() og name. Klassen ContentWriter erklærer også et nyt felt posts.

Bemærk, at private medlemmer af en forældreklasse ikke arves af barneklassen.

5.1 Parent constructor: super() in constructor ()

Hvis du vil ringe til parent constructor i en børneklasse, skal du brugesuper() specialfunktionen, der er tilgængelig i child constructor.,

For eksempel, lad os gøre ContentWriter konstruktør kalder forælder konstruktøren af User, samt initialisere indlæg felt:

super(name) i barnets klasse ContentWriter udfører konstruktøren af den overordnede klasse User.

Bemærk, at inden i barnekonstruktøren skal du udføre super()før du bruger this nøgleord. Opkald super() sørger for, at forældrekonstruktøren initialiserer forekomsten.,

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

5.2 Overordnet instans: super i metoder

Hvis du gerne vil have adgang til den overordnede metode indersiden af et barn metode, du kan bruge særlige genvej super.

getName() af barnets klasse ContentWriter giver adgang til den metode super.getName() direkte fra den overordnede klasse User.

denne funktion kaldes metode tvingende.

Bemærk, at du også kan bruge super med statiske metoder for at få adgang til forældrenes statiske metoder.

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 er polymorf: operatøren registrerer et barn som en forekomst af forældreklassen.

writer er et eksempel på børneklassen ContentWriter. Operatøren writer instanceof ContentWriter evaluerer til true.

på samme tid ContentWriter er en børneklasse af User. Så writer instanceof User evaluerer til true også.

Hvad hvis du gerne vil bestemme den nøjagtige klasse af forekomsten?, Du kan bruge constructor ejendom og sammenligne direkte med klassen:

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

7. Klasser og prototyper

jeg må sige, at klassesynta .en i JavaScript gør et godt stykke arbejde for at abstrahere fra den prototype arv. For at beskriveclass syntaks har jeg ikke engang brugt udtrykket prototype.

men klasserne er bygget oven på den prototypiske arv. Hver klasse er en funktion og skaber en instans, når den påberåbes som konstruktør.

de følgende to kodestykker er ækvivalente.,

klassen-version:

Den version, ved hjælp af prototype:

Den klasse syntaks er langt nemmere at arbejde, hvis du er fortrolig med den klassiske arv mekanisme af Java eller Swift sprog. alligevel, selvom du bruger klassesynta.i JavaScript, anbefaler jeg dig at have et godt greb om prototypisk arv.

8. Klassefunktioner tilgængelighed

klassefunktionerne, der præsenteres i dette indlæg, er spredt over ES2015 og forslag på trin 3.,

Ved udgangen af 2019, klassen funktioner er fordelt mellem:

  • Offentlige og private eksempel felter er del af Klassens felter forslag
  • Privat instans, metoder og adgangsmetoder er en del af Klassen private metoder, forslag
  • Offentlige og private statiske felter og private statiske metoder er en del af Klassen statiske funktioner forslag
  • resten er en del af ES2015 standard.

9. Konklusion

JavaScript-klasser initialiserer forekomster med konstruktører, definerer felter og metoder., Du kan vedhæfte felter og metoder selv på selve klassen ved hjælp af static nøgleord.

arv opnås ved hjælp af extends nøgleord: du kan nemt oprette en børneklasse fra en forælder. super søgeord bruges til at få adgang til forældreklassen fra en børneklasse.

for at drage fordel af indkapsling skal du gøre felterne og metoderne private til at skjule de interne detaljer i dine klasser. De private felter og metoder Navne skal begynde med #.,

klasserne i JavaScript bliver mere og mere praktiske at bruge.

Hvad synes du om at bruge # til præfiks private ejendomme?