Programmering

JavaScript-opplæring: Funksjoner med høyere ordre

I forrige uke droppet jeg tilfeldigvis begrepet "høyere ordensfunksjon" når jeg snakket om notater. Mens jeg føler meg komfortabel med å kaste rundt ord som det nå, visste jeg ikke alltid hva de betydde. Denne uken skal vi undersøke hva som er høyere ordensfunksjoner, vise noen vanlige eksempler og lære hvordan vi kan gå frem for å lage våre egne.

I sin kjerne er en høyere ordensfunksjon bare en funksjon som aksepterer en funksjon som et argument eller returnerer en funksjon. Dette er mulig i JavaScript takket være førsteklasses funksjoner, noe som betyr at funksjoner i JavaScript kan sendes rundt som alle andre variabler. Selv om dette høres ganske greit ut, telegraferer det ikke helt den typen kraft du har med førsteklasses funksjoner.

Hvis du skriver JavaScript, har du sannsynligvis brukt høyere ordensfunksjoner og ikke engang lagt merke til det. Hvis du noen gang har byttet ut en til loop med en matrisemetode, har du brukt funksjoner av høyere orden. Hvis du noen gang har brukt resultatene av et AJAX-anrop (uten asynkronisering/avvente), har du brukt høyere ordensfunksjoner (både løfter og tilbakeringing innebærer høyere ordensfunksjoner). Hvis du noen gang har skrevet en React-komponent som viser en liste over elementer, har du brukt funksjoner av høyere orden. La oss se disse eksemplene:

const items = ['a', 'b', 'c', 'd', 'e']

// I stedet for dette for loop ....

for (la i = 0; i <items.length - 1; i ++) {

console.log (varer [i]);

}

// Vi kan bruke forEach, en høyere ordensfunksjon

// (forEach tar en funksjon som et argument)

items.forEach ((item) => console.log (item));

// Tilbakekallinger eller løfter, hvis du gir

// asynkrone forespørsler, du bruker

// høyere ordensfunksjoner

get ('// aws.random.cat/meow', (respons) => {

putImageOnScreen (respons.file);

});

get ('// random.dog/woof.json').then((response) => {

putImageOnScreen (respons.file);

});

// I React-komponenten nedenfor brukes kart,

// som er en høyere ordensfunksjon

const myListComponent = (rekvisitter) => {

komme tilbake (

   

    {props.items.map ((item) => {

    komme tilbake (

  • {punkt}
  • )

          })}

      );

    };

Dette er eksempler på høyere ordensfunksjoner som godtar funksjoner som argumenter, men mange av dem returnerer også funksjoner. Hvis du noen gang har sett et funksjonsanrop som har to par parenteser, er det en høyere ordensfunksjon. Denne typen ting pleide å være mindre vanlig, men hvis du i det hele tatt jobber med Redux, har du sannsynligvis brukt koble funksjon, som er en høyere ordensfunksjon:

eksporter standardtilkobling (mapStateToProps, mapDispatchToProps) (MyComponent);

I saken ovenfor ringer vi koble med to argumenter, og den returnerer en funksjon, som vi umiddelbart kaller med ett argument. Du har kanskje også sett (eller skrevet) et enkelt loggbibliotek som bruker funksjoner som returverdier. I eksemplet nedenfor oppretter vi en logger som logger konteksten før meldingen:

const createLogger = (context) => {

returner (msg) => {

console.log (`$ {context}: $ {msg}`);

  }

};

const log = createLogger ('myFile');

logg ('En veldig viktig melding');

// logger ut "myFile: En veldig viktig melding"

Eksemplet ovenfor begynner å illustrere noe av kraften til høyere ordensfunksjoner (se også mitt forrige innlegg om memoisering). Noter det createLogger tar et argument som vi refererer i kroppen til funksjonen vi returnerer. Den returnerte funksjonen, som vi tilordner variabelen Logg, kan fremdeles få tilgang til kontekst argument fordi det var i omfanget der funksjonen ble definert.

Morsomt faktum: Henvisning kontekst muliggjøres av nedleggelser. Jeg kommer ikke til å avslutte her fordi de fortjener sitt eget innlegg, men de kan brukes sammen med funksjoner av høyere orden for noen virkelig interessante effekter.

For eksempel, bruk av lukking sammen med funksjoner av høyere ordre pleide å være den eneste måten vi kunne ha "private" eller manipulasjonssikre variabler i JavaScript:

la protectedObject = (funksjon () {

la myVar = 0;

komme tilbake {

få: () => myVar,

økning: () => myVar ++,

  };

})();

protectedObject.get (); // returnerer 0

protectedObject.increment ();

protectedObject.get (); // returnerer 1

myVar = 42; // vips! du opprettet nettopp en global variabel

protectedObject.get (); // returnerer fortsatt 1

La oss ikke la oss rive med. Funksjoner med høyere ordre krever ikke noe fancy som nedleggelser. De er ganske enkelt funksjoner som tar andre funksjoner som argumenter eller som returnerer funksjoner. Full stopp. Hvis du vil ha flere eksempler eller videre lesing, kan du sjekke kapittelet om funksjoner av høyere orden i “Eloquent JavaScript” av Marijn Haverbeke.

Spørsmål eller kommentarer? Ta gjerne kontakt på Twitter: @freethejazz.

$config[zx-auto] not found$config[zx-overlay] not found