Wat is super() in JavaScript?

0
7

Wat gebeurt er als je ziet wat JavaScript-oproepen dat super()?.In een child class gebruik je super() op te roepen de ouders op de constructor en super.<methodName> om toegang te krijgen tot de ouders op de methoden. In dit artikel zullen we aannemen dat op zijn minst een beetje vertrouwd met de concepten van constructeurs en kind en ouder klassen. Als dat is totaal nieuw, wilt u misschien om te beginnen met Mozilla ‘ s artikel op Object-oriented JavaScript voor beginners.

Super is het niet uniek om Javascript te veel programmeertalen, zoals Java en Python, hebben een super() trefwoord dat zorgt voor een verwijzing naar een bovenliggende klasse. JavaScript, in tegenstelling tot Java en Python, is niet gebouwd rond een klasse erfenis model. In plaats daarvan, het strekt zich uit van JavaScript ‘ s prototypal erfenis model te bieden gedrag dat consistent is met klasse erfenis.

Laten we leren een beetje meer over en kijken naar een aantal code voorbeelden.

Ten eerste, hier is een citaat van Mozilla ‘ s web documenten voor de klassen:

JavaScript klassen, geïntroduceerd in ECMAScript 2015, voornamelijk syntactische suiker over JavaScript bestaande prototype-gebaseerde overerving. De klasse syntaxis is niet de invoering van een nieuw object-georiënteerde erfenis model te JavaScript.

Een voorbeeld van een eenvoudige kind en ouder klasse zullen helpen illustreren wat dit citaat eigenlijk betekent:

Zie de Pen
ZEzggLK door Bailey Jones (@bailey_jones)
op CodePen.

Mijn voorbeeld zijn de volgende twee klassen: vis en forel. Alle vissen hebben informatie voor habitat en lengte, dus die eigenschappen behoren tot de vis klasse. Forel heeft ook een woning voor verscheidenheid, dus het verlengt vis te bouwen op de top van de andere twee eigenschappen. Hier worden de aannemers voor vis en forel:

class vis, {
constructor(habitat, lengte) {
deze.habitat = habitat
deze.lengte = lengte
}
}

klasse forel strekt zich uit vis {
constructor(habitat, lengte, variety”)) {
super(habitat, lengte)
deze.verscheidenheid = verschillende
}
}

De vis klasse constructor definieert habitat en de lengte, en de forel constructor definieert verscheidenheid. Ik noem super() forel, constructor, of ik krijg een verwijzing weergegeven wanneer ik probeer om dit in te stellen.verscheidenheid. Dat komt omdat op de lijn een van de forel klasse, ik zei het JavaScript dat de forel is een kind van vis met behulp van het strekt zich uit trefwoord. Dat betekent forel dit kader bevat de eigenschappen en methoden die zijn gedefinieerd in de vis klasse, plus welke eigenschappen en methoden forel bepaalt voor zichzelf. Super() aanroept in wezen laat JavaScript weten wat een vis, dus dat kan het maken van een deze context voor forel, het omvat alles van vis, plus alles wat we over te definiëren voor de forel. De vis klasse hoeft niet super() omdat de “ouders” is gewoon het JavaScript-Object. Vis is al aan de top van de prototypal erfenis keten, dus bellen super() is niet nodig — vis is in deze context alleen moet zijn Object, die JavaScript reeds op de hoogte.

De prototypal erfenis model voor vis en forel en de eigenschappen die beschikbaar zijn op de in deze context voor elk van hen. Vanaf de top, de prototypal overervingsketen hier gaat het Object → vis → forel.

Ik belde super(habitat, de lengte) forel constructor (het raadplegen van het vis-klasse), waardoor alle drie de eigenschappen direct beschikbaar op de deze context voor de forel. Eigenlijk is er een andere manier om hetzelfde gedrag van de forel constructor. Ik moet bellen super() om te voorkomen dat een fout in de verwijzing, maar ik hoef het niet te noemen het “goed” met de parameters die vis constructor verwacht. Dat komt omdat ik niet hoef te gebruiken super() om waarden toe te kennen aan de velden die vis maakt — ik moet er alleen voor zorgen dat deze velden bestaan op forel deze context. Dit is een belangrijk verschil tussen JavaScript en een echte klasse erfenis model, zoals Java, waar de volgende code kan illegaal zijn afhankelijk van hoe gelegd ik de vis klasse:

klasse forel strekt zich uit vis {
constructor(habitat, lengte, variety”)) {
super()
deze.habitat = habitat
deze.lengte = lengte
deze.verscheidenheid = verschillende
}
}

Deze alternatieve forel constructor maakt het moeilijker om te vertellen welke eigenschappen behoren tot de vis en die behoren tot forel, maar het krijgt hetzelfde resultaat als in het vorige voorbeeld. Het enige verschil is dat hier, super() aanroept zonder parameters maakt u de eigenschappen van de habitat en de lengte op de huidige deze context, zonder het toewijzen van alles voor hen. Als ik de naam van de console.log in(deze) na regel drie, het zou print {habitat: undefined, lengte: undefined}. Lijnen vier en vijf waarden toekennen.

Kan ik ook super() buiten forel constructor om aan te referentiemethoden op de bovenliggende klasse. Ik heb hier een renderProperties methode die het weergeven van de eigenschappen van de klasse in de HTML-element dat ik pas aan toe. super() is handig hier, want ik wil mijn forel klasse voor het implementeren van een soortgelijke methode die doet hetzelfde, plus nog een beetje meer — het kent een class naam van het element voor het bijwerken van de HTML. Ik kan opnieuw de logica van de vis klasse door te bellen super.renderProperties() in de relevante klasse-functie.

class vis, {
renderProperties(element) {
element.innerHTML = JSON.stringify(deze)
}
}

klasse forel strekt zich uit vis {
renderPropertiesWithSuper(element) {
element.className=”green”
super.renderProperties(element);
}

De naam die je kiest is belangrijk. Ik heb mijn methode in de forel-klasse renderPropertiesWithSuper() want ik wil nog steeds de mogelijkheid hebben om te bellen forel.renderProperties() zoals dat is gedefinieerd op de vis klasse. Als ik zou gewoon de naam van de functie in de forel-klasse renderProperties, dat zou volkomen geldig te zijn; echter, ik zou niet meer in staat om toegang te krijgen tot beide functies rechtstreeks van een instantie van forel – bellen forel.renderProperties zou het aanroepen van de functie gedefinieerd op forel. Dit is niet per se een handige implementatie – het is misschien wel een beter patroon voor een functie die gesprekken super zoals deze te overschrijven van de bovenliggende functie naam – maar het illustreert hoe flexibel JavaScript staat in uw lessen te worden.

Het is volledig mogelijk om de uitvoering van dit voorbeeld zonder gebruik te maken van de super() of breidt de trefwoorden die werden zo nuttig in het vorige voorbeeld, het is gewoon veel minder handig. Dat is wat Mozilla bedoeld met “syntactische suiker.” In feite, als ik aangesloten op mijn vorige code in een transpiler zoals Babel om ervoor te zorgen dat mijn klassen gewerkt met oudere versies van JavaScript, het zou leiden tot iets dichter naar de volgende code. Hier de code is meestal hetzelfde, maar dan zult u merken dat zonder verlengt en super(), ik heb te definiëren vissen naar forel en als functies en toegang tot hun prototypes direct. Ik heb ook wel wat extra bedrading op de lijnen 15, 16 en 17 te stellen forel als een kind van vis en ervoor zorgen dat de forel kan worden doorgegeven van de juiste deze context in de constructor. Als je geïnteresseerd bent in een diepe duik in wat hier aan de hand, Eric Groen heeft een uitstekende post met veel code voorbeelden voor het bouwen van klassen met en zonder ES2015.

Zie de Pen
wvvdxdd door Bailey Jones (@bailey_jones)
op CodePen.

Klassen in JavaScript zijn een krachtige manier om te delen functionaliteit. Klasse componenten in Reageren, bijvoorbeeld op hen rekenen. Echter, als je gewend bent om met Object Georiënteerd programmeren in een andere taal die gebruikmaakt van een klasse erfenis model, JavaScript-gedrag kan soms verrassend zijn. Het leren van de grondbeginselen van prototypal erfenis kan helpen verduidelijken hoe te werken met klassen in JavaScript.