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:
- Felter på klasse-eksempel
- Felter på klassen selv (aka statisk)
De felter, der også har 2 niveauer af adgang:
- Public: området er tilgængeligt overalt
- 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 static
efterfulgt 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 static
efterfulgt af en almindelig metodesynta.: static myStaticMethod() { ... }
.
Når du arbejder med statiske metoder, der er 2 simple regler at huske:
- En statisk metode kan få adgang til de statiske felter
- 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?