introduktion
JavaScript är ett prototypbaserat språk, och varje objekt i JavaScript har en dold intern egenskap som heter ]
som kan användas för att utöka objektegenskaper och metoder. Du kan läsa mer om prototyper i vår förståelse prototyper och arv i JavaScript handledning.
tills nyligen använde industriella Utvecklare konstruktionsfunktioner för att efterlikna ett objektorienterat designmönster i JavaScript., Språkspecifikationen ECMAScript 2015, ofta kallad ES6, introducerade klasser till JavaScript-språket. Klasser i JavaScript erbjuder faktiskt inte ytterligare funktionalitet, och beskrivs ofta som ”syntaktiskt socker” över prototyper och arv genom att de erbjuder en renare och mer elegant syntax. Eftersom andra programmeringsspråk använder klasser gör klassens syntax i JavaScript det enklare för utvecklare att flytta mellan språk.
klasser är funktioner
en JavaScript-klass är en typ av funktion., Klasser deklareras med nyckelordetclass
. Vi kommer att använda funktionen uttryck syntax för att initiera en funktion och klass uttryck syntax för att initiera en klass.
// Initializing a function with a function expressionconst x = function() {}
// Initializing a class with a class expressionconst y = class {}
vi kan komma åt]
för ett objekt med metodenObject.getPrototypeOf()
. Låt oss använda det för att testa den tomma funktionen vi skapade.
Object.getPrototypeOf(x);
Outputƒ () { }
Vi kan också använda den metoden på den klass vi just skapat.,
Object.getPrototypeOf(y);
Outputƒ () { }
koden deklareras medfunction
ochclass
båda returnerar en funktion]
. Med prototyper kan vilken funktion som helst bli en konstruktörsinstans med hjälp av nyckelordet new
.
Outputx {}constructor: ƒ ()
detta gäller även klasser.
Outputy {}constructor: class
dessa prototypkonstruktorsexempel är annars tomma, men vi kan se hur båda metoderna uppnår samma slutresultat under syntaxen.,
definiera en klass
i prototyper och arv handledning, skapade vi ett exempel baserat runt karaktärsskapande i ett textbaserat rollspel. Låt oss fortsätta med det exemplet här för att uppdatera syntaxen från funktioner till klasser.
en konstruktörsfunktion initieras med ett antal parametrar, som skulle tilldelas som Egenskaper för this
, med hänvisning till själva funktionen. Den första bokstaven i identifieraren skulle kapitaliseras genom konvention.
// Initializing a constructor functionfunction Hero(name, level) { this.name = name; this.level = level;}
När vi översätter detta till klassens syntax, som visas nedan, ser vi att det är strukturerat mycket på samma sätt.
// Initializing a class definitionclass Hero { constructor(name, level) { this.name = name; this.level = level; }}
vi vet att en konstruktörsfunktion är avsedd att vara en objektkopia av kapitaliseringen av initialiseringens första bokstav (vilket är valfritt) och genom förtrogenhet med syntaxen. Nyckelordetclass
kommunicerar på ett enklare sätt målet för vår funktion.,
den enda skillnaden i initieringens syntax är att använda nyckelordet class
istället för function
och tilldela egenskaperna i en constructor()
– metod.
Defining Methods
den vanliga praxisen med konstruktörsfunktioner är att tilldela metoder direkt tillprototype
istället för i initialiseringen, vilket ses igreet()
– metoden nedan.
med klasser denna syntax förenklas, och metoden kan läggas direkt till klassen., Med hjälp av metoden definition stenografi infördes i ES6, definiera en metod är en ännu mer kortfattad process.
Låt oss ta en titt på dessa egenskaper och metoder i aktion. Vi kommer att skapa en ny instans avHero
med hjälp av nyckelordetnew
och tilldela vissa värden.
const hero1 = new Hero('Varg', 1);
om vi skriver ut mer information om vårt nya objekt med console.log(hero1)
kan vi se mer information om vad som händer med klassinitieringen.,
OutputHero {name: "Varg", level: 1}__proto__: ▶ constructor: class Hero ▶ greet: ƒ greet()
Vi kan se i utgången att funktionernaconstructor()
ochgreet()
tillämpades på funktionerna__proto__
, eller]
av funktionernahero1
, och inte direkt som en metod på objektethero1
. Även om detta är klart när konstruktörsfunktioner görs, är det inte uppenbart när du skapar klasser. Klasser möjliggör en enklare och kortfattad syntax, men offrar lite klarhet i processen.,
utöka en klass
en fördelaktig egenskap hos konstruktörsfunktioner och klasser är att de kan utökas till nya objektritningar baserade utanför föräldern. Detta förhindrar upprepning av kod för objekt som är liknande men behöver några ytterligare eller mer specifika funktioner.
nya konstruktionsfunktioner kan skapas från den överordnade med metodencall()
., I exemplet nedan kommer vi att skapa en mer specifik teckenklass som heter Mage
och tilldela egenskaperna för Hero
till den med call()
, samt lägga till en extra egenskap.
vid denna tidpunkt kan vi skapa en ny instans av Mage
med samma egenskaper som Hero
samt en ny som vi lagt till.,
const hero2 = new Mage('Lejon', 2, 'Magic Missile');
skickahero2
till konsolen, vi kan se att vi har skapat en nyMage
baserat på konstruktören.
OutputMage {name: "Lejon", level: 2, spell: "Magic Missile"}__proto__: ▶ constructor: ƒ Mage(name, level, spell)
med ES6-klasser används nyckelordetsuper
I stället förcall
för att komma åt de överordnade funktionerna. Vi kommer att användaextends
för att hänvisa till den överordnade klassen.
Nu kan vi skapa en nyMage
– instans på samma sätt.,
const hero2 = new Mage('Lejon', 2, 'Magic Missile');
Vi kommer att skriva uthero2
till konsolen och visa utmatningen.
OutputMage {name: "Lejon", level: 2, spell: "Magic Missile"}__proto__: Hero ▶ constructor: class Mage
utmatningen är nästan exakt densamma, förutom att ]
I klasskonstruktionen är kopplad till föräldern, i det här fallet Hero
.
nedan är en sida vid sida jämförelse av hela processen för initiering, lägga till metoder, och arv av en konstruktor funktion och en klass.
även om syntaxen är helt annorlunda är det underliggande resultatet nästan detsamma mellan båda metoderna. Klasser ger oss ett mer koncist sätt att skapa objektritningar, och konstruktionsfunktioner beskriver mer exakt vad som händer under huven.
slutsats
i den här handledningen lärde vi oss om likheterna och skillnaderna mellan JavaScript-konstruktörsfunktioner och ES6-klasser. Både klasser och konstruktörer efterliknar en objektorienterad arvmodell till JavaScript, vilket är ett prototypbaserat arvsspråk.,
att förstå prototypisk arv är av största vikt för att vara en effektiv JavaScript-utvecklare. Att vara bekant med klasser är oerhört användbart, eftersom populära JavaScript-bibliotek som React ofta använder syntaxen class
.