Jak správně zabalit funkci JavaScriptu

, Author

Zabalení funkcí JavaScriptu umožňuje přidat běžnou logiku do funkcí, které nemáte pod kontrolou, jako jsou nativní a externí funkce. Mnoho knihoven JavaScriptu, jako například agenti TrackJS, potřebují ke své práci obalovat externí funkce. Přidání obalů nám umožňuje naslouchat telemetrii, chybám a protokolům ve vašem kódu, aniž byste museli explicitně volat naše rozhraní API.

Možná budete chtít obalit funkci, abyste přidali instrumentaci nebo dočasnou logiku ladění. Můžete také změnit chování externí knihovny, aniž byste museli měnit zdrojový kód.

Základní obtékání funkcí

Protože je JavaScript úžasně dynamický, můžeme funkci obtékat tak, že ji jednoduše nadefinujeme něčím novým. Vezměme si například toto obalení funkce myFunction:

V tomto triviálním příkladu jsme obalili původní funkci myFunction a přidali k ní zprávu o přihlášení. Ale spoustu věcí jsme neřešili:

  • Jak předáme argumenty funkce?
  • Jak zachováme rozsah (hodnotu this)?
  • Jak získáme návratovou hodnotu?
  • Co když dojde k chybě?

Abychom si s těmito věcmi poradili, musíme být v našem obalování trochu chytřejší.

Všimněte si, že v tomto příkladu funkci pouze nevyvoláváme, ale call-ujeme ji s hodnotou pro this a argumenty a, b a c. Hodnota this bude předána z místa, kam připojíte obalenou funkci, v tomto příkladu Window.

Celou funkci jsme také obklopili blokem try/catch, abychom mohli v případě chyby vyvolat vlastní logiku, znovu ji vyhodit nebo vrátit výchozí hodnotu.

Pokročilé obtékání funkcí

Základní příklad obtékání bude fungovat v 90 % případů, ale pokud vytváříte sdílené knihovny, jako jsou agenti TrackJS, nestačí to! Abychom mohli obalovat funkce jako profesionálové, měli bychom se vypořádat s některými okrajovými případy:

  • Co s nedeklarovanými nebo neznámými argumenty?
  • Jak přizpůsobit signaturu funkce?
  • Jak zrcadlit vlastnosti funkce?

Jsou zde 3 jemné, ale důležité změny. Za prvé (#1) jsme funkci pojmenovali. Zdá se to zbytečné, ale uživatelský kód může kontrolovat hodnotu function.name, takže je důležité zachovat název při obalování.

Druhá změna (#2) je ve způsobu, jakým jsme obalovanou funkci volali – místo call jsme použili apply. To nám umožňuje předat objekt arguments, což je objekt podobný poli všech argumentů předaných funkci za běhu. To nám umožňuje podporovat funkce, které mohou mít nedefinovaný nebo proměnný počet argumentů.

Pomocí apply nepotřebujeme argumenty a, b a c definované v signatuře funkce. Ale tím, že nadále deklarujeme stejné argumenty jako původní funkce, zachováváme aritu funkce. To znamená, že Function.length vrátí počet argumentů definovaných v signatuře, a to bude zrcadlit původní funkci.

Závěrečná změna (#3) zkopíruje všechny uživatelem zadané vlastnosti z původní funkce na náš obal.

Omezení

Tento obal je důkladný, ale v JavaScriptu vždy existují omezení. Konkrétně je obtížné správně obalit funkci s nestandardním prototypem, například konstruktor objektu. Tento případ použití lépe řeší dědičnost.

Obecně je změna prototypu funkce možná, ale není to dobrý nápad. Manipulace s prototypy má vážné výkonnostní důsledky a nezamýšlené vedlejší účinky.

Respektujte prostředí

Obalení funkce vám dává velké možnosti instrumentovat a manipulovat s prostředím JavaScriptu. Máte odpovědnost za to, abyste s touto mocí nakládali moudře. Pokud vytváříte obaly funkcí, nezapomeňte respektovat uživatele a prostředí, ve kterém pracujete. Mohou existovat další wrappery, další posluchači připojení k událostem a očekávání týkající se rozhraní API funkcí. Postupujte opatrně a nenarušujte externí kód.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.