JavaScript-Tutorial: Funktionen höherer Ordnung

Letzte Woche habe ich beiläufig den Begriff „Funktion höherer Ordnung“ gestrichen, wenn ich über Memoisierung gesprochen habe. Obwohl ich mich jetzt wohl fühle, solche Begriffe herumzuwerfen, wusste ich nicht immer, was sie bedeuteten. Diese Woche werden wir untersuchen, was Funktionen höherer Ordnung sind, einige gängige Beispiele zeigen und lernen, wie wir unsere eigenen erstellen.

Im Kern ist eine Funktion höherer Ordnung nur eine Funktion, die eine Funktion als Argument akzeptiert oder eine Funktion zurückgibt. Dies ist in JavaScript dank erstklassiger Funktionen möglich, sodass Funktionen in JavaScript wie jede andere Variable weitergegeben werden können. Das klingt zwar ziemlich einfach, aber es telegraphiert nicht ganz die Leistung, die Sie mit erstklassigen Funktionen haben.

Wenn Sie JavaScript schreiben, haben Sie wahrscheinlich Funktionen höherer Ordnung verwendet und es nicht einmal bemerkt. Wenn Sie jemals eine forSchleife durch eine Array-Methode ersetzt haben, haben Sie Funktionen höherer Ordnung verwendet. Wenn Sie jemals die Ergebnisse eines AJAX-Aufrufs (ohne async/ await) verwendet haben, haben Sie Funktionen höherer Ordnung verwendet (sowohl Versprechen als auch Rückrufe beinhalten Funktionen höherer Ordnung). Wenn Sie jemals eine React-Komponente geschrieben haben, die eine Liste von Elementen anzeigt, haben Sie Funktionen höherer Ordnung verwendet. Sehen wir uns diese Beispiele an:

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

// Stattdessen for-Schleife ....

für (sei i = 0; i <items.length - 1; i ++) {

  console.log (items [i]);

}}

// Wir können forEach verwenden, eine Funktion höherer Ordnung

// (forEach übernimmt eine Funktion als Argument)

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

// Rückrufe oder Versprechen, wenn Sie machen

// asynchrone Anforderungen, die Sie verwenden

// Funktionen höherer Ordnung

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

  putImageOnScreen (response.file);

});

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

  putImageOnScreen (response.file);

});

// In der folgenden React-Komponente wird map verwendet.

// das ist eine Funktion höherer Ordnung

const myListComponent = (Requisiten) => {

  Rückkehr (

   

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

            Rückkehr (

  • {Artikel}
  • )

          })}

      );

    };

Dies sind Beispiele für Funktionen höherer Ordnung, die Funktionen als Argumente akzeptieren, aber viele von ihnen geben auch Funktionen zurück. Wenn Sie jemals einen Funktionsaufruf mit zwei Klammern gesehen haben, ist dies eine Funktion höherer Ordnung. Diese Art von Dingen war früher weniger verbreitet, aber wenn Sie überhaupt mit Redux arbeiten, haben Sie wahrscheinlich die connectFunktion verwendet, die eine Funktion höherer Ordnung ist:

Standardverbindung exportieren (mapStateToProps, mapDispatchToProps) (MyComponent);

Im obigen Fall rufen wir connectmit zwei Argumenten auf und es wird eine Funktion zurückgegeben, die wir sofort mit einem Argument aufrufen. Möglicherweise haben Sie auch eine einfache Protokollierungsbibliothek gesehen (oder geschrieben), die Funktionen als Rückgabewerte verwendet. Im folgenden Beispiel erstellen wir einen Logger, der seinen Kontext vor der Nachricht protokolliert:

const createLogger = (Kontext) => {

  return (msg) => {

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

  }}

};

const log = createLogger ('myFile');

log ('Eine sehr wichtige Nachricht');

// meldet sich ab "myFile: Eine sehr wichtige Nachricht"

Das obige Beispiel zeigt einige der Möglichkeiten von Funktionen höherer Ordnung (siehe auch meinen vorherigen Beitrag zum Memoisieren). Beachten Sie, dass createLoggerein Argument verwendet wird, auf das wir im Hauptteil der von uns zurückgegebenen Funktion verweisen. Diese zurückgegebene Funktion, die wir der Variablen zuweisen log, kann weiterhin auf das contextArgument zugreifen , da sie sich in dem Bereich befand, in dem die Funktion definiert wurde.

Unterhaltsame Tatsache: Die Referenzierung contextwird durch Verschlüsse ermöglicht. Ich werde hier nicht auf Schließungen eingehen, weil sie ihren eigenen Beitrag verdienen, aber sie können in Verbindung mit Funktionen höherer Ordnung für einige wirklich interessante Effekte verwendet werden.

Beispielsweise war die Verwendung von Verschlüssen zusammen mit Funktionen höherer Ordnung die einzige Möglichkeit, in JavaScript „private“ oder manipulationssichere Variablen zu verwenden:

let protectedObject = (function () {

  lass myVar = 0;

  Rückkehr {

    get: () => myVar,

    Inkrement: () => myVar ++,

  };

}) ();

protectedObject.get (); // gibt 0 zurück

protectedObject.increment ();

protectedObject.get (); // gibt 1 zurück

myVar = 42; // whoops! Sie haben gerade eine globale Variable erstellt

protectedObject.get (); // gibt immer noch 1 zurück

Lassen wir uns jedoch nicht mitreißen. Funktionen höherer Ordnung erfordern nichts Besonderes wie Verschlüsse. Es sind einfach Funktionen, die andere Funktionen als Argumente verwenden oder Funktionen zurückgeben. Punkt. Wenn Sie weitere Beispiele oder weitere Informationen wünschen, lesen Sie das Kapitel über Funktionen höherer Ordnung in „Eloquent JavaScript“ von Marijn Haverbeke.

Fragen oder Kommentare? Fühlen Sie sich frei, auf Twitter zu erreichen: @freethejazz.