JavaScript blir ofte feiltolket som en Object-orientert språk, men i virkeligheten er det ikke sant; JavaScript er et prototypebasert språk. Arv i JavaScript oppnås av noe som heter Prototypisk arv. For å forstå det, må vi først være kjent med hvordan en konstruktør fungerer i JavaScript, hvordan et objekt opprettes mot en konstruktør, og hva som er prototypekjetting.
Dette er et av de avanserte temaene i JavaScript, og vi kommer til å ta deg veldig tregt og prøve å forklare hver eneste liten informasjon sammen med utdrag, la oss komme i gang.
Hvordan fungerer en konstruktør i JavaScript
Konvensjonelt, Konstruktører er spesielle funksjoner som utføres hver gang et objekt opprettes mot en klasse; I JavaScript, hvert funksjonsuttrykk er en Konstruktør. Hvis du kommer fra et trivielt programmeringsspråk og har litt bakgrunn med objektorientert programmering, vil du bli forvirret. Prøv derfor ikke å sammenligne JavaScript-konsepter med triviell objektorientert programmering.
Selv om det med ankomsten av ES 6 -versjonen av JavaScript nøkkelordet "Klasse”Ble lagt til i JavaScript, men det brukes ikke til å implementere arvekonseptet. I JavaScript kan du lage objekter som er kartlagt på funksjonen, ja - funksjoner.
Se for deg en funksjon opprettet med følgende kode:
var person = funksjon ()Som nevnt ovenfor, at hvert funksjonsuttrykk er en konstruktør, kan dette bevises ved å bruke følgende linjer inne i funksjonen:
var person = funksjon (navn)Nå, som du ser, lager vi en funksjon og inne i funksjonens kropp, definerer vi og initialiserer egenskapene til objektet, akkurat som vi gjør i en normal konvensjonell konstruktør. La oss nå lage noen gjenstander som er kartlagt til dette Personens Konstruktørfunksjon med følgende kodelinjer:
var p1 = ny person ("John");Nå lager vi objekter, men vi har ingen metode i objekter som vil gi oss navnet på personen vi nettopp opprettet, så la oss lage den funksjonen inne i konstruktøren til Person gjenstand.
var person = funksjon (navn)Nå må vi kalle denne funksjonen fra hvert enkelt objekt ved å bruke følgende kodelinjer:
konsoll.Logg (P1.getName ());Etter å ha kjørt hele utdraget får vi følgende utgang på konsollen:
Nå er her det største problemet med å bruke denne typen mal, forestill deg at du har 100 objekter av Person, Disse 100 objektene vil ha sine egen 100 annerledes getName() Funksjoner:
Dette er fordi disse objektene er forekomstene av Person, dermed gjøre det overflødig på minnet. Det er her Prototypeegenskaper kommer i spill.
Prototypeegenskapen
Hver funksjon og hvert objekt har en egenskap som er navngitt Prototype, Denne prototypen inneholder metoder og egenskaper til en funksjon, og denne prototypeegenskapen deles mellom alle forekomster/objekter som er kartlagt til funksjonen, ta en titt på dette utdraget:
Hvis vi skulle lage noen objekter basert på denne funksjonen “x”, Ville de arve metodene og egenskapene i“prototype”Av funksjonen. I vårt eksempel ville hovedfunksjonen være Person Og gjenstandene er P1, P2, som:
Bruke prototypeegenskaper for å lage prototypisk arv
Vårt viktigste problem med den trivielle tilnærmingen var at hvert eneste objekt hadde sin egen getName() Funksjoner, jo mer gjenstandene desto mer er antallet av getName() Funksjoner i minnet. For å fjerne dette, skriver vi getName () -funksjon Utenfor konstruktøruttrykket og inne i prototypeegenskapen ved hjelp av syntaks:
ObjectName.prototype.MethodNameKoden vår endres til:
var person = funksjon (navn)Utgangen er nøyaktig den samme som forrige gang:
Men forskjellen denne gangen er at snarere enn at hvert objekt har sin egen getName() Funksjon, hvert objekt får tilgang til getName() Funksjon i foreldrene og bruke den funksjonen til å utføre instruksjonen gitt til den. Dette kalles "Prototypisk arv”I JavaScript. Etter hvert, ikke gjør det overflødig i minnet.
Masterobjekt
Alt i JavaScript er egentlig et objekt, dette betyr at alt i JavaScript er basert på Gjenstand (med en kapital o).
For å forklare dette, bruk følgende kodelinjer og åpne konsollen i nettleseren.
var demo = funksjon ()Du lager en funksjon med en tom konstruktør og konsoll.dir() Viser detaljene om demo() Funksjonsdefinisjon på konsollen, du vil se dette:
Utvid den lille pilspissen, og undersøk __proto__ egenskap til denne funksjonen, __proto__ Eiendom forteller oss om hvilket objekt som ble kartlagt, vil du se dette:
La oss nå lage en forekomst av denne demo -funksjonen og undersøke den __proto__ som:
var demo = funksjon ()Etter å ha kjørt denne koden, bør du se følgende utdata på konsollen:
Utvid dette og undersøk konstruktøren som forekomsten “X” ble kartlagt, vil du se:
Som betyr det objektet x har foreldredemoen, og vi vet allerede at Funksjonsdemoer kartlagt på JavaScript -objektet. Dette skaper en prototypingkjede som:
Objektet "x”Kan få tilgang til metodene og egenskapene til hovedobjektet, og dermed skape en arvekjede.
Hvis vi ser i konsollen vår for siste gang, kan vi undersøke at hovedobjektet har denne ene metoden i sin prototypeegenskap som er toString () som:
Og vi kaller denne egenskapen på objektet “x”Og på funksjonen demo som du opprettet som:
konsoll.Logg (x.toString ());Du får utdataene som:
Du kan se, både objektet og funksjonen kunne få tilgang til denne metoden, selv om den ikke ble definert i dem.
Slik fungerer arv i JavaScript gjennom prototyper.
Konklusjon
Arv i JavaScript er veldig forskjellig fra vår konvensjonelle definisjon av arv i objektorientert programmering. I JavaScript oppnår vi arv ved hjelp av en eiendom som heter prototype. Du lærte hvordan en konstruktør fungerer i JavaScript, hva er prototype Eiendom, hvordan alt i JavaScript er et objekt ved å lære om Masterobjekt. Dessuten lærte du om prototypisk arv og prototypekjedering, og du kunne få tilgang til metodene og egenskapene til Masterobjekt bruker gjenstand som du opprettet.