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!