u schrijft JavaScript en plotseling beseffen met afschuw en angst dat u een enorme functie hebt geschreven. Het is de beste van ons overkomen. Nu komt de bijna onstuitbare drang om de functie in kleinere stukken te scheiden.
grote functies betekenen veel verantwoordelijkheden op één plaats en mogelijk ook code geur, dus het is een goed idee op zich. Maar je wilt de functie zo opsplitsen dat hij zijn betekenis of context niet verliest. Om dat te doen, moet je denken methode chaining – ook wel functie chaining. Dit artikel zal uitleggen wat ik daarmee bedoel.
Prerequisites
voordat we beginnen, zijn hier enkele JavaScript-concepten die u al bekend moet zijn:
- Arrow-functies
- Array-methoden
- Async-functies
de meeste ervaren ontwikkelaars zullen enige ervaring hebben met Array
– methoden, zoals map, reduce en filter. Je bent waarschijnlijk al zoiets als dit tegengekomen.:
const food = ;// This type of usage is very commonfood .map(item => item.type) .reduce((result, fruit) => { result.push(fruit); return ; }, );// result:
methode chaining gebeurt wanneer u meerdere functies wilt aanroepen met behulp van hetzelfde object en de referentie ervan. In het bovenstaande voorbeeld geeft de MatriXmethode map
een Array
terug, die een formidabel aantal methoden heeft.
omdat u een referentie retourneert die wijst naar een Array
, hebt u toegang tot alle eigenschappen van Array
. Het is hetzelfde principe dat je gebruikt voor je eigen methode chaining.
beter begrijpen
Ik zal niet alle nuances van this
behandelen, maar het is goed om te begrijpen waarom this
werkt zoals het doet. Het maakt niet uit hoe ervaren je bent, het trefwoord dit kan moeilijk te begrijpen. Het is vaak de reden waarom dingen niet werken zoals je verwacht dat ze te 😅.
hier is de kern van het: this
zal altijd wijzen naar de huidige scope
of instantie van waar het wordt genoemd. Een voorbeeld:
const dog = { is: null, log: () => console.log(this.is), bark() { this.is = "woofing"; this.log(); return this; }, walk() { this.is = "walking"; this.log(); return this; }, eat() { this.is = "eating"; this.log(); return this; }};dog .bark() .eat() .walk();
als je een functie als deze schrijft (geen woordspeling bedoeld), wil je misschien methoden ketenen die gerelateerd zijn aan het object. Het object dog
heeft 3 methoden: walk
, bark
en eat
. Elke keer als ik een van zijn functies noem, moet een console de weergave tonen van wat de hond precies op dat moment doet.
maar daar is een probleem mee. Als je het in de browser uitvoert, zul je beseffen dat het niet werkt zoals verwacht. Dat komt omdat pijlfuncties lexicale scoping gebruiken, waarbij this
verwijst naar de omringende scope – in dit geval window
, niet het object zelf.
om dat op te lossen, moeten we een anonieme functie aanroep gebruiken om de eigenschap log
weer te geven:
// instead of this: log: () => console.log(this.is),// use this: log() { console.log(this.is); }
nu zal de scope this
van de hond toegankelijk zijn binnen de functie.
met klasse
u kunt hetzelfde resultaat bereiken met klassen:
class Dog { is = null; log() { console.log(this.is); } bark() { this.is = "woofing"; this.log(); return this; } walk() { this.is = "walking"; this.log(); return this; } eat() { this.is = "eating"; this.log(); return this; }}const dog = new Dog();dog .bark() .eat() .walk();
Prototype
Als u prototype moet gebruiken, doe het dan op deze manier:
function Dog() {}Dog.prototype.is = null;Dog.prototype.log = function() { console.log(this.is);};Dog.prototype.bark = function() { this.is = "woofing"; this.log(); return this;};Dog.prototype.walk = function() { this.is = "walking"; this.log(); return this;};Dog.prototype.eat = function() { this.is = "eating"; this.log(); return this;};const dog = new Dog();dog .bark() .eat() .walk();
Hoe Zit Het Met Async-Functies?
async
functies zijn synthetische suiker voor promises en generatoren. Wanneer u een async
functie declareert, weet u dat deze een belofte retourneert. Daarom heb je ook toegang tot alle methoden van de belofte.
const requests = { user: null, action: null, log(something) { console.log(this); }, async getUser() { this.user = await new Promise(resolve => { setTimeout(() => { resolve("Douglas Pires"); }, 1000); }); this.log("user"); return this; }, async registerAction() { this.action = await new Promise(resolve => { setTimeout(() => { resolve("programming stuff"); }, 1000); }); this.log("action"); return this; }};requests.getUser().then(() => requests.registerAction());
het is echter geen goed idee om een aantal beloften samen te ketenen. Ik raad aan om in plaats daarvan een aantal await
sleutelwoorden te gebruiken. Het is makkelijker en het zal uw code veel leesbaarder te maken.
await requests.getUser(); // Douglas Piresawait requests.registerAction(); // programming
en u heeft hier toegang tot dezelfde eigenschappen:
console.log(requests.user); // Douglas Piresconsole.log(requests.action); // programming
concluderend
Chaining functies zijn handig wanneer u een object moet manipuleren. Het is ook een praktische manier om de leesbaarheid van uw code te verbeteren. Echter, zoals je hierboven hebt gezien, je moet keten verstandig.
In dit artikel hebben we gesproken over this
, klassen, prototypes en async
functies in de context van JavaScript methode chaining. Ik hoop dat je hebt opgepikt een aantal nuttige tips en zijn nu beter geïnformeerd over het onderwerp. U kunt mijn repository met alle code op JavaScript methode chaining hier vinden. Tot ziens in de volgende post!
met plezier dit artikel gelezen? Voel je vrij om te delen op social media met behulp van de knoppen hieronder. Als alternatief heb ik ook geschreven over hoe je een kleurenpalet generator kunt bouwen met behulp van Nuxt en Vuetify. Ga kijken!