Indledning
JavaScript er et prototype-baseret sprog, og alle objekter i JavaScript har en skjult indre egenskab, der kaldes ]
, der kan bruges til at udvide objekt egenskaber og metoder. Du kan læse mere om prototyper i vores forståelse prototyper og arv i JavaScript tutorial.
indtil for nylig brugte flittige udviklere konstruktørfunktioner til at efterligne et objektorienteret designmønster i JavaScript., Sprogspecifikationen ECMAScript 2015, ofte omtalt som ES6, introducerede klasser til JavaScript-sproget. Klasser i JavaScript tilbyder faktisk ikke yderligere funktionalitet, og beskrives ofte som at give “syntaktisk sukker” over prototyper og arv, idet de tilbyder en renere og mere elegant syntaks. Fordi andre programmeringssprog bruger klasser, gør klassesynta .en i JavaScript det mere ligetil for udviklere at flytte mellem sprog.
klasser er funktioner
en JavaScript-klasse er en type funktion., Klasser erklæres med class
nøgleord. Vi vil bruge funktionsudtrykssynta.til at initialisere en funktion og klasseudtrykssynta. til at initialisere en klasse.
// Initializing a function with a function expressionconst x = function() {}
// Initializing a class with a class expressionconst y = class {}
Vi kan få adgang til de ]
af et objekt ved hjælp af Object.getPrototypeOf()
metode. Lad os bruge det til at teste den tomme funktion, vi oprettede.
Object.getPrototypeOf(x);
Outputƒ () { }
Vi kan også bruge denne metode på den klasse, vi lige har oprettet.,
Object.getPrototypeOf(y);
Outputƒ () { }
Den kode, der er erklæret med function
og class
begge tilbage en funktion ]
. Med prototyper kan enhver funktion blive en konstruktørforekomst ved hjælp af new
nøgleord.
Outputx {}constructor: ƒ ()
dette gælder også for klasser.
Outputy {}constructor: class
disse prototypekonstruktøreksempler er ellers tomme, men vi kan se, hvordan begge metoder under syntaksen opnår det samme slutresultat.,
definition af en klasse
i prototyper og arv tutorial, skabte vi et eksempel baseret omkring karakter skabelse i et tekstbaseret rollespil. Lad os fortsætte med dette eksempel her for at opdatere syntaksen fra funktioner til klasser.
en konstruktørfunktion initialiseres med et antal parametre, som ville blive tildelt som Egenskaber for this
, med henvisning til selve funktionen. Det første bogstav i identifikatoren ville blive aktiveret ved konvention.
// Initializing a constructor functionfunction Hero(name, level) { this.name = name; this.level = level;}
Når vi oversætter dette til klassesynta .en, vist nedenfor, ser vi, at den er struktureret meget på samme måde.
// Initializing a class definitionclass Hero { constructor(name, level) { this.name = name; this.level = level; }}
Vi ved, at en konstruktørfunktion er beregnet til at være en objektplan ved kapitalisering af initialisatorens første bogstav (som er valgfri) og gennem fortrolighed med syntaksen. class
søgeord kommunikerer på en mere ligetil måde målet med vores funktion.,
Den eneste forskel i syntaksen af initialiseringen er at bruge class
søgeord i stedet for function
, og tildele egenskaber inde i en constructor()
metode.
Definere Metoder
Den fælles praksis med constructor-funktioner er at tildele metoder direkte til prototype
i stedet for i initialiseringen, som det ses i greet()
metode nedenfor.
med klasser er denne syntaks forenklet, og metoden kan tilføjes direkte til klassen., Ved hjælp af metoden definition stenografi indført i ES6, definere en metode er en endnu mere kortfattet proces.
lad os se på disse egenskaber og metoder i aktion. Vi opretter en ny forekomst af Hero
ved hjælp af new
nøgleord og tildeler nogle værdier.
const hero1 = new Hero('Varg', 1);
Hvis vi printer ud af mere information om vores nye objekt med console.log(hero1)
, kan vi se flere detaljer om, hvad der sker med den klasse initialisering.,
OutputHero {name: "Varg", level: 1}__proto__: ▶ constructor: class Hero ▶ greet: ƒ greet()
Vi kan se i output, at constructor()
og greet()
funktioner blev anvendt til __proto__
, eller ]
af hero1
og ikke direkte som en metode, der på det hero1
objektet. Selvom dette er klart, når man laver konstruktørfunktioner, er det ikke indlysende, mens man opretter klasser. Klasser giver mulighed for en mere enkel og kortfattet syntaks, men ofrer en vis klarhed i processen.,
udvidelse af en klasse
et fordelagtigt træk ved konstruktørfunktioner og klasser er, at de kan udvides til nye objektplaner baseret på forælderen. Dette forhindrer gentagelse af kode for objekter, der ligner hinanden, men har brug for nogle yderligere eller mere specifikke funktioner.
nye konstruktørfunktioner kan oprettes fra forælderen ved hjælp af call()
– metoden., I eksemplet nedenfor opretter vi en mere specifik karakterklasse kaldet Mage
, og tildeler egenskaberne for Hero
til det ved hjælp af call()
, samt tilføjelse af en ekstra egenskab.
På dette punkt, kan vi oprette en ny instans af Mage
ved hjælp af de samme egenskaber som Hero
samt en ny, vi har tilføjet.,
const hero2 = new Mage('Lejon', 2, 'Magic Missile');
Sender hero2
til konsollen, kan vi se, at vi har skabt en ny Mage
baseret off konstruktøren.
OutputMage {name: "Lejon", level: 2, spell: "Magic Missile"}__proto__: ▶ constructor: ƒ Mage(name, level, spell)
Med ES6 klasser, super
søgeord er brugt i stedet for call
for at få adgang til de overordnede funktioner. Vi vil bruge extends
for at henvise til forældreklassen.
nu kan vi oprette en ny Mage
instans på samme måde.,
const hero2 = new Mage('Lejon', 2, 'Magic Missile');
Vi vil udskrive hero2
til konsollen, og se resultatet.
OutputMage {name: "Lejon", level: 2, spell: "Magic Missile"}__proto__: Hero ▶ constructor: class Mage
udgangen er næsten nøjagtig den samme, bortset fra at i klassekonstruktionen er]
knyttet til forælderen, i dette tilfældeHero
.
nedenfor er en side-by-side sammenligning af hele processen med initialisering, tilføjelse af metoder og arv af en konstruktørfunktion og en klasse.
selvom syntaksen er helt anderledes, er det underliggende resultat næsten det samme mellem begge metoder. Klasser giver os en mere præcis måde at skabe objekt tegninger, og konstruktør funktioner beskriver mere præcist, hvad der sker under hætten.
konklusion
i denne vejledning lærte vi om ligheder og forskelle mellem JavaScript-konstruktørfunktioner og ES6-klasser. Både klasser og konstruktører efterligner en objektorienteret arvemodel til JavaScript, som er et prototypebaseret arvesprog.,forståelse af prototypisk arv er afgørende for at være en effektiv JavaScript-udvikler. At være bekendt med klasser er yderst nyttigt, da populære JavaScript-biblioteker som React gør hyppig brug afclass
syntaks.