Programiranje

Vadnica za JavaScript: Funkcije višjega reda

Prejšnji teden sem nenamerno izpustil izraz »funkcija višjega reda«, ko sem govoril o spominjanju. Čeprav se zdaj dobro počutim s takšnimi izrazi, nisem vedno vedel, kaj pomenijo. Ta teden bomo preučili, kaj so funkcije višjega reda, prikazali nekaj pogostih primerov in se naučili, kako se lotiti ustvarjanja lastnih.

V bistvu je funkcija višjega reda le funkcija, ki funkcijo sprejme kot argument ali vrne funkcijo. To je v JavaScript mogoče zaradi prvovrstnih funkcij, kar pomeni, da je mogoče funkcije v JavaScript prenašati tako kot katero koli drugo spremenljivko. Čeprav se to sliši precej preprosto, pa ne telegrafira povsem tiste vrste moči, ki jo imate s prvovrstnimi funkcijami.

Če pišete JavaScript, ste verjetno uporabili funkcije višjega reda in tega sploh niste opazili. Če ste kdaj zamenjali a za zanko z metodo matrike, ste uporabili funkcije višjega reda. Če ste kdaj uporabili rezultate klica AJAX (brez asinh/čakati), ste uporabljali funkcije višjega reda (obljube in povratni klici vključujejo funkcije višjega reda). Če ste že kdaj napisali komponento React, ki prikazuje seznam elementov, ste uporabili funkcije višjega reda. Poglejmo te primere:

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

// Namesto tega za zanko ....

za (naj je i = 0; i <items.length - 1; i ++) {

console.log (elementi [i]);

}

// Lahko uporabimo forEach, funkcijo višjega reda

// (forEach vzame funkcijo kot argument)

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

// Povratni klici ali obljube, če dajete

// asinhrone zahteve, ki jih uporabljate

// funkcije višjega reda

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

putImageOnScreen (response.file);

});

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

putImageOnScreen (response.file);

});

// V spodnji komponenti React je uporabljen zemljevid,

// ki je funkcija višjega reda

const myListComponent = (rekviziti) => {

vrnitev (

   

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

    vrnitev (

  • {element}
  • )

          })}

      );

    };

To so primeri funkcij višjega reda, ki funkcije sprejemajo kot argumente, vendar jih veliko vrne tudi funkcije. Če ste kdaj videli klic funkcije, ki ima dva nabora oklepajev, je to funkcija višjega reda. Včasih so bile takšne stvari manj pogoste, če pa sploh sodelujete z Reduxom, ste verjetno uporabili povezati funkcija, ki je funkcija višjega reda:

izvoz privzete povezave (mapStateToProps, mapDispatchToProps) (MyComponent);

V zgornjem primeru pokličemo povezati z dvema argumentoma in vrne funkcijo, ki jo takoj pokličemo z enim argumentom. Morda ste že videli (ali napisali) preprosto knjižnico beleženja, ki uporablja funkcije kot povratne vrednosti. V spodnjem primeru bomo ustvarili zapisovalnik dnevnikov, ki pred sporočilom zabeleži svoj kontekst:

const createLogger = (context) => {

vrnitev (sporočilo) => {

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

  }

};

const log = createLogger ('myFile');

log ('Zelo pomembno sporočilo');

// odjavi se "myFile: Zelo pomembno sporočilo"

Zgornji primer začne ponazarjati nekaj moči funkcij višjega reda (glej tudi mojo prejšnjo objavo o memoizaciji). Upoštevajte to createLogger vzame argument, na katerega se sklicujemo v telesu funkcije, ki jo vrnemo. Ta vrnjena funkcija, ki jo dodelimo spremenljivki log, lahko še vedno dostopa do kontekstu argument, ker je bil v obsegu, kjer je bila funkcija definirana.

Zabavno dejstvo: sklicevanje kontekstu omogoča zaprtje. Tu se ne bom spuščal, ker si zaslužijo svojo objavo, vendar jih je mogoče uporabiti skupaj s funkcijami višjega reda za nekaj res zanimivih učinkov.

Na primer, uporaba zapore skupaj s funkcijami višjega reda je bila včasih edini način, kako lahko v JavaScript imamo "zasebne" ali spremenljive spremenljivke:

naj protectedObject = (function () {

naj je myVar = 0;

vrni {

get: () => myVar,

prirast: () => myVar ++,

  };

})();

protectedObject.get (); // vrne 0

protectedObject.increment ();

protectedObject.get (); // vrne 1

myVar = 42; // ups! pravkar ste ustvarili globalno spremenljivko

protectedObject.get (); // še vedno vrne 1

Ne zanašamo pa se. Funkcije višjega reda ne zahtevajo ničesar modnega, kot so zapiranja. So preprosto funkcije, ki druge funkcije jemljejo kot argumente ali ki vrnejo funkcije. Pika. Če želite več primerov ali nadaljnje branje, si oglejte poglavje o funkcijah višjega reda v "Zgovornem JavaScriptu" Marijn Haverbeke.

Vprašanja ali komentarji? Vas prosimo, da se obrnete na Twitter: @freethejazz.

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