Method Chaining i JavaScript

du skriver JavaScript och inser plötsligt med skräck och rädsla att du har skrivit en enorm funktion. Det har hänt de bästa av oss. Nu kommer den nästan ostoppbara lusten att separera funktionen i mindre bitar.

stora funktioner betyder mycket ansvar på ett ställe och eventuellt kod luktar också, så det är en bra ide i sig. Men du vill bryta upp funktionen på ett sådant sätt att den inte förlorar sin mening eller sammanhang. För att göra det måste du tänka metod kedja – även kallad funktion kedja. Denna artikel kommer att förklara vad jag menar med det.

förutsättningar

innan vi börjar, här är några JavaScript-koncept som du redan behöver känna till:

  • Arrow functions
  • Array methods
  • async functions

de flesta erfarna utvecklare kommer att ha viss erfarenhet av Array metoder, såsom map, reduce och filter. Du har förmodligen redan stött på något liknande:

const food = ;// This type of usage is very commonfood .map(item => item.type) .reduce((result, fruit) => { result.push(fruit); return ; }, );// result: 

metod kedja händer när du vill ringa flera funktioner med samma objekt och dess referens. I exemplet ovan returnerar matrismetoden map en Array, som har ett formidabelt antal metoder.

eftersom du returnerar en referens som pekar på en Array har du tillgång till alla egenskaper för Array. Det är samma princip som du använder för din egen metod kedja.

bättre förstå detta

jag kommer inte att täcka alla nyanser av this, men det är bra att förstå varför this fungerar som det gör. Oavsett hur erfaren Du är, nyckelordet detta kan vara svårt att förstå. Det är ofta anledningen till att saker och ting inte fungerar som du förväntar dig att de ska äta.

här är kärnan i det: this kommer alltid att peka på den aktuella scope eller instansen där den heter. Ett exempel:

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();

när du skriver en funktion som denna (no pun intended) kanske du vill kedja metoder som är relaterade till objektet. Objektet dog har 3 metoder: walk, bark och eat. Varje gång jag ringer till någon av dess funktioner, bör en konsol visa representationen av vad hunden gör just nu.

men det finns ett problem med det. Om du kör den i webbläsaren inser du att den inte fungerar som förväntat. Det beror på att pilfunktioner använder lexikal scoping, där this hänvisar till dess omgivande omfattning – i detta fall window, inte själva objektet.

för att lösa det bör vi använda ett anonymt funktionsanrop för att representera egenskapen log :

// instead of this: log: () => console.log(this.is),// use this: log() { console.log(this.is); }

nu kommer hundens this omfattning att vara tillgänglig inuti funktionen.

använda Klass

du kan uppnå samma resultat med klasser:

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();

använda prototyp

om du måste använda prototyp, gör det så här:

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();

Vad Sägs Om Asynkfunktioner?

async funktioner är syntetiskt socker för löften och generatorer. När du deklarerar en async – funktion vet du att den kommer att returnera ett löfte. På grund av det har du också tillgång till alla metoder för löftet.

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());

det är dock inte bra att kedja en massa löften tillsammans. Jag rekommenderar att du använder en massa await nyckelord istället. Det är lättare och det kommer att göra din kod mycket mer läsbar.

await requests.getUser(); // Douglas Piresawait requests.registerAction(); // programming

och du har tillgång till samma egenskaper här:

console.log(requests.user); // Douglas Piresconsole.log(requests.action); // programming

Sammanfattningsvis

Kedjefunktioner är praktiska när du måste manipulera ett objekt. Det är också ett praktiskt sätt att förbättra läsbarheten för din kod. Men som du har sett ovan bör du kedja klokt.

i den här artikeln har vi pratat om this, klasser, prototyper och async funktioner i samband med JavaScript-metodkedja. Jag hoppas att du har plockat upp några användbara tips och är nu bättre informerade om ämnet. Du kan hitta mitt förråd med all kod på JavaScript – metodkedjning här. Vi ses i nästa post!

Tyckte du om att läsa den här artikeln? Dela gärna på sociala medier med knapparna nedan. Alternativt har jag också skrivit om hur du kan bygga en färgpalett generator med Nuxt och Vuetify. Gå kolla in det!

Lämna ett svar

Din e-postadress kommer inte publiceras.