Programování

Výukový program pro JavaScript: Funkce vyššího řádu

Minulý týden jsem nedbale upustil od termínu „funkce vyššího řádu“, když jsem mluvil o memoizaci. I když se nyní cítím dobře, když se mi podobné výrazy hodí, ne vždy jsem věděl, co znamenají. Tento týden prozkoumáme, co jsou funkce vyššího řádu, ukážeme několik běžných příkladů a naučíme se, jak postupovat při vytváření vlastních.

Ve svém jádru je funkce vyššího řádu jen funkcí, která přijímá funkci jako argument nebo vrací funkci. To je v JavaScriptu možné díky prvotřídním funkcím, což znamená, že funkce v JavaScriptu lze předávat jako jakoukoli jinou proměnnou. I když to zní docela jednoduše, není to tak docela telegrafní, jaký máte výkon s prvotřídními funkcemi.

Pokud píšete JavaScript, pravděpodobně jste použili funkce vyššího řádu a ani jste si toho nevšimli. Pokud jste někdy vyměnili a pro smyčka s metodou pole, použili jste funkce vyššího řádu. Pokud jste někdy použili výsledky volání AJAX (bez asynchronní/čekat), použili jste funkce vyššího řádu (sliby i zpětná volání zahrnují funkce vyššího řádu). Pokud jste někdy napsali komponentu React, která zobrazuje seznam položek, použili jste funkce vyššího řádu. Podívejme se na tyto příklady:

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

// Místo toho pro smyčku ....

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

console.log (položky [i]);

}

// Můžeme použít forEach, funkci vyššího řádu

// (forEach bere funkci jako argument)

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

// Zpětná volání nebo sliby, pokud děláte

// asynchronní požadavky, které používáte

// funkce vyššího řádu

get ('// aws.random.cat/meow', (odpověď) => {

putImageOnScreen (response.file);

});

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

putImageOnScreen (response.file);

});

// V níže uvedené komponentě React se používá mapa,

// což je funkce vyššího řádu

const myListComponent = (rekvizity) => {

vrátit se (

   

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

    vrátit se (

  • {položka}
  • )

          })}

      );

    };

Jedná se o příklady funkcí vyššího řádu, které přijímají funkce jako argumenty, ale spousta z nich také vrací funkce. Pokud jste někdy viděli volání funkce, která má dvě sady závorek, jedná se o funkci vyššího řádu. Takové věci bývaly méně časté, ale pokud s Reduxem vůbec pracujete, pravděpodobně jste to využili připojit funkce, což je funkce vyššího řádu:

exportovat výchozí připojení (mapStateToProps, mapDispatchToProps) (MyComponent);

Ve výše uvedeném případě voláme připojit se dvěma argumenty a vrátí funkci, kterou okamžitě zavoláme jedním argumentem. Možná jste také viděli (nebo napsali) jednoduchou knihovnu protokolování, která používá funkce jako návratové hodnoty. V níže uvedeném příkladu vytvoříme záznamník, který před zprávou zaznamená jeho kontext:

const createLogger = (kontext) => {

návrat (zpráva) => {

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

  }

};

const log = createLogger ('myFile');

log („velmi důležitá zpráva“);

// odhlásí se „myFile: velmi důležitá zpráva“

Výše uvedený příklad začíná ilustrovat některé z funkcí funkcí vyššího řádu (viz také můj předchozí příspěvek o memoizaci). Všimněte si, že createLogger vezme argument, na který odkazujeme v těle funkce, kterou vrátíme. Tato vrácená funkce, kterou jsme přiřadili proměnné log, může i nadále přistupovat k kontext argument, protože to bylo v oboru, kde byla funkce definována.

Zábavný fakt: odkazování kontext je umožněno uzávěry. Nebudu se zde zabývat závěry, protože si zaslouží svůj vlastní příspěvek, ale mohou být použity ve spojení s funkcemi vyššího řádu pro některé opravdu zajímavé efekty.

Například používání uzávěrů spolu s funkcemi vyššího řádu bývalo jediným způsobem, jak jsme mohli mít v JavaScriptu „soukromé“ nebo proměnné odolné proti neoprávněné manipulaci:

nech ProtectedObject = (funkce () {

nech myVar = 0;

vrátit se {

get: () => myVar,

přírůstek: () => myVar ++,

  };

})();

protectedObject.get (); // vrátí 0

protectedObject.increment ();

protectedObject.get (); // vrátí 1

myVar = 42; // Jejda! právě jste vytvořili globální proměnnou

protectedObject.get (); // stále vrátí 1

Nenechme se však unést. Funkce vyššího řádu nevyžadují nic fantastického, jako jsou uzávěry. Jsou to jednoduše funkce, které berou jiné funkce jako argumenty nebo které vracejí funkce. Tečka. Pokud chcete více příkladů nebo více informací, podívejte se na kapitolu o funkcích vyššího řádu v „Eloquent JavaScript“ od Marijn Haverbeke.

Dotazy nebo připomínky? Neváhejte kontaktovat na Twitteru: @freethejazz.

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