A JavaScript függvények becsomagolásával közös logikát adhatsz hozzá olyan függvényekhez, amelyeket nem te irányítasz, mint a natív és külső függvények. Sok JavaScript könyvtárnak, mint például a TrackJS ügynököknek, külső függvényeket kell becsomagolniuk a munkájukhoz. A burkolatok hozzáadása lehetővé teszi, hogy figyeljük a Telemetriát, a hibákat és a naplókat a kódjában, anélkül, hogy explicit módon meg kellene hívnia az API-nkat.
Elképzelhető, hogy instrumentálási vagy ideiglenes hibakeresési logika hozzáadásához szeretne burkolni egy függvényt. Egy külső könyvtár viselkedését is megváltoztathatja anélkül, hogy a forrást módosítania kellene.
Basic Function Wrapping
Mivel a JavaScript csodálatosan dinamikus, egy függvényt úgy tudunk becsomagolni, hogy egyszerűen átdefiniáljuk a függvényt valami újjal. Nézzük például a myFunction
ilyen csomagolását:
Ebben a triviális példában az eredeti myFunction
-ot csomagoltuk be, és hozzáadtunk egy naplózási üzenetet. De van egy csomó dolog, amit nem kezeltünk:
- Hogyan adjuk át a függvény argumentumait?
- Hogyan tartjuk fenn a hatókörünket (a
this
értékét)? - Hogyan kapjuk meg a visszatérési értéket?
- Mi van, ha hiba történik?
Hogy ezeket a dolgokat kezelni tudjuk, egy kicsit ügyesebbnek kell lennünk a csomagolásban.
Megjegyezzük, hogy ebben a példában nem csak meghívjuk a függvényt, hanem call
-ezzük a this
értékével és a a
, b
és c
argumentumokkal. A this
értékét onnan fogjuk átadni, ahová a beburkolt függvényünket csatoltuk, ebben a példában Window
.
A teljes függvényt egy try/catch
blokkba is bekerítettük, hogy hiba esetén egyéni logikát hívhassunk, újra dobhassuk, vagy egy alapértelmezett értéket adhassunk vissza.
Edményes függvénycsomagolás
Az alap csomagolási példa az esetek 90%-ában működik, de ha megosztott könyvtárakat építesz, mint például a TrackJS ügynökök, akkor ez nem elég jó! Ahhoz, hogy profi módon csomagoljuk a függvényeinket, van néhány éles eset, amivel foglalkoznunk kell:
- Mi van a be nem jelentett vagy ismeretlen argumentumokkal?
- Hogyan illesszük a függvény aláírásába?
- Hogyan tükrözzük a függvény tulajdonságait?
Három finom, de fontos változás van. Először is (#1), elneveztük a függvényt. Ez redundánsnak tűnik, de a felhasználói kód ellenőrizheti a function.name
értékét, ezért fontos a név megtartása a csomagolás során.
A második változás (#2) abban van, hogy hogyan hívjuk a csomagolt függvényt, call
helyett apply
-t használunk. Ez lehetővé teszi számunkra, hogy átadjunk egy arguments
objektumot, amely egy tömbszerű objektum a függvénynek futásidőben átadott összes argumentumból. Ez lehetővé teszi számunkra, hogy támogassuk azokat a függvényeket, amelyeknek meghatározatlan vagy változó számú argumentuma lehet.
A apply
segítségével nincs szükségünk a függvény aláírásában definiált a
, b
és c
argumentumokra. De azzal, hogy továbbra is ugyanazokat az argumentumokat deklaráljuk, mint az eredeti függvényben, megtartjuk a függvény aritását. Vagyis a Function.length
az aláírásban definiált argumentumok számát adja vissza, és ez tükrözi az eredeti függvényt.
Az utolsó módosítás (#3) az eredeti függvény felhasználó által megadott tulajdonságait átmásolja a csomagolásunkra.
Korlátozások
Ez a csomagolás alapos, de a JavaScriptben mindig vannak korlátok. Különösen nehéz helyesen becsomagolni egy nem szabványos prototípussal rendelkező függvényt, például egy objektumkonstruktort. Ezt a felhasználási esetet jobban megoldja az öröklés.
A függvény prototípusának megváltoztatása általában lehetséges, de nem jó ötlet. A prototípusok manipulálása komoly teljesítménykövetkezményekkel és nem kívánt mellékhatásokkal jár.
Respect the Environment
A függvénycsomagolás nagy hatalmat ad a JavaScript-környezet instrumentálására és manipulálására. Felelősséggel tartozol azért, hogy ezt a hatalmat bölcsen használd. Ha függvénycsomagolást készít, ügyeljen arra, hogy tiszteletben tartsa a felhasználót és a környezetet, amelyben dolgozik. Előfordulhat, hogy más burkolatok vannak érvényben, más hallgatók vannak csatolva az eseményekhez, és elvárások vannak a függvény API-kkal szemben. Lépjen óvatosan, és ne törje meg a külső kódot.