Articles

rövid bevezetés a Metaprogramozáshoz JavaScript-ben

reflexió

reflexió, nem tetszett “kódgenerálás”, egy folyamat a nyelv mögöttes mechanikájának megváltoztatására. A reflexió történhet fordítási időben vagy futásidőben, de ragaszkodunk a futásidejű reflexióhoz, mivel a JavaScript-ről beszélünk, így a fordítási idejű reflexió nem lesz lehetséges. Az itt tárgyalt fogalmak azonban alkalmazhatók lehetnek egy lefordított nyelvre is.

mivel megértettük, hogy a reflexió a nyelv mögöttes mechanikájának megváltoztatásáról szól, három fő kategóriába sorolták, nevezetesen. önvizsgálat, közbenjárás és módosítás.

introspekció

az introspekció a program elemzésének folyamata. Ha meg tudja mondani, hogy mit csinál a program, módosíthatja azt a tetszése szerint. Annak ellenére, hogy egyes programozási nyelvek nem támogatják a kódgenerálást vagy a kódmódosítási funkciókat, de valószínűleg lehetővé teszik az önellenőrzést.

az önvizsgálat egyszerű példája a typeofvagy instanceof operátorok használata a JavaScript-ben. A typeof egy érték (vagy egy értéket visszaadó kifejezés) aktuális adattípusát adja vissza, míg a instanceof visszatér true vagy false ha az LHS érték RHS osztály példánya. Lássuk őket akcióban.

(bevezetés/önvizsgálat.

a fenti programban a typeof and instanceof operátorokat használtuk a coerce függvényben a bejövő adatok szippantására value. Ez az önvizsgálat alapvető bemutatása. A kifejezetten a metaprogramozásra tervezett nyelv azonban néhány hatékony önvizsgálati eszközt nyújthat.

a in operátorral ellenőrizheti, hogy létezik-e tulajdonság az objektumban. AisNaN globális függvény ellenőrzi, hogy az objektumNaN. Van néhány statikus módszer a Object a Object típus értékeinek ellenőrzésére, például Object.isFrozen(value) annak ellenőrzésére, hogy a value lefagyott vagy Object.keys(value) a value objektum tulajdonságneveinek lekéréséhez.

az ES5-ig ezekkel az operátorokkal és módszerekkel dolgoztunk. Az ES2015-ben (ES6) a JavaScript bevezette a Reflect objektumot, amely statikus módszereket biztosít (csakúgy, mint a Object), de kifejezetten önvizsgálatra tervezték. Mivel külön leckénk van a Reflect – ről, ezeket a módszereket ott tárgyaljuk.

közbenjárás

a közbenjárás a JavaScript folyamatokba való beavatkozás és a folyamat szokásos viselkedésének módosítása. A JavaScript nagyszerű eszközöket biztosít a közbenjáráshoz, amelyek közül az egyik Proxy.

a Proxy osztályt az ES2015 (ES6) – ben vezették be az alapvető JavaScript műveletek elfogására (beavatkozására) az objektumok körül, ahogy fentebb láttuk, de sokkal szebb módon. Külön tanulságunk van a Proxy (hamarosan), de dióhéjban a Proxy elfogható logikát csomagol egy objektum köré.

var targetWithProxy = new Proxy(target, handler);

itt a targetobjektum és handler az elfogó. A handler szintén egyszerű JavaScript objektum, de néhány értelmes mezővel. For example, handler.get would be a function that returns a custom value when target.prop (here, prop is any property) is accessed.

(introduction/proxy.js)

Proxy is a great way to provide abstractions over your not-so-public data. Például a fenti programban absztrakciókat adtunk a target objektum felett, és testre szabtuk, hogyan kell bemutatnia magát a nyilvánosság számára.

némi közbenjárás lehetséges volt az ES5-ben is, például a getterés setterstulajdonságleírókon, de ez a target objektum mutációját eredményezné. Proxysokkal tisztább módot kínál a közbenjárás elérésére az eredeti objektum módosítása nélkül (target).

módosítás

a Módosítás a program viselkedésének mutációval történő módosítását jelenti. Közbenjárás esetén csak a szokásos JavaScript folyamatokat fogtuk el úgy, hogy elfogó logikát adtunk a cél és a vevő között, anélkül, hogy károsítanánk a célt. Ebben az esetben a módosítás, megváltoztatjuk a viselkedését a cél maga, így illik a vevő.

egy függvény implementációjának felülbírálása jó példa lenne a módosításra. Például, ha EGY függvényt úgy terveztek, hogy egy bizonyos módon viselkedjen, de feltételesen valami mást akarunk, akkor ezt megtehetjük egy önálló felülbíráló funkció megtervezésével. Lássunk egy példát.

(bevezetés/funkció-módosítás.js)

a fenti példában létrehoztunk egy függvényt, amely felülírja magát egy új funkció implementációval. Ez lenne a legkeményebb példa a módosításra, de vannak más, talán értelmesebb Felhasználási eseteink is.

(bevezetés/csak olvasható-objektum.js)

a fenti példában a Object.defineProperty() módszert használtuk a name tulajdonság alapértelmezett tulajdonságleírójának megváltoztatására annak érdekében, hogy csak olvasható legyen. Használhatja a Object.freeze() módszert is a teljes objektum zárolására a mutációk elkerülése érdekében.

egyes közbenjárások módosításokkal történhetnek, ahogy a fenti példából is. A writable:false beállításával az objektum tulajdonságleírójában, tehát az objektum mutálásával (belső megvalósítás), elfogadtuk az érték-hozzárendelési műveletet.

Ha nem ismeri a valueOf módszert, akkor arra szolgál, hogy egy objektumot primitív értékre kényszerítsen. Tehát ha van egy objektumom ,amelynekvalueOf metódusa van önmagában vagy a prototípus láncán, akkor ezt a metódust a JavaScript hívja meg, amikor aritmetikai műveletet próbál végrehajtani rajta. Alapértelmezés szerint a Objectrendelkezik a valueOf metódussal, amely visszaadja magát (az objektumot).

(bevezetés/érték.js)

mint látható a fenti példában, emp1/10 eredménye egy NaN mivel egy objektum nem osztható fel, mint a természetes számok. De később hozzáadtuk avalueOf metódust aEmployee osztályhoz, amely visszaadja asalary objektum értékét. Ezért emp2/10 visszaadott 200 mivel emp2.salary jelentése 200. Hasonlóképpen, emp3/10 visszaadott 300 ahogy hozzáadtuk valueOf módszer közvetlenül a emp3.

tehát a fenti példa minden lépésénél beavatkozunk, hogy egy objektum hogyan kerül bemutatásra egy szabványos JavaScript művelethez, és megváltoztatjuk a viselkedését a mi tetszésünkre. Ez nem más, mint a közbenjárás.

az ES2015-ben (ES6) a JavaScript egy új primitív adattípust vezetett be, amely symbol. Ez nem olyan, mint amit korábban láttunk, és nem lehet szó szerinti formában ábrázolni. Csak a Symbol függvény meghívásával hozható létre.

var sym1 = Symbol();
var sym2 = Symbol();
var sym3 = Symbol('description'); // description for debugging aidsym1 === sym2 // false
sym1 === sym2 // falsetypeof sym1 // 'symbol'console.log( sym1 ); // 'Symbol()'
console.log( sym3 ); // 'Symbol(description)'

dióhéjban egyedi értékeket állít elő, amelyek normál objektumkulcsként is használhatók aobjjelölés használatával, ahol akey szimbólum lenne.

var key = Symbol();var obj = {
name: 'Ross',
: 200
};console.log( obj.name ); // 'Ross'
console.log( obj ); // 200
Object.keys(obj); // obj = 300;

mivel egyediek, véletlenül nem lehet duplikált szimbólumot létrehozni. Minden új szimbólum egyedi (létrehozva a Symbol() használatával), ami azt jelenti, hogy ha ugyanazt a szimbólumot szeretné használni, akkor ezt el kell tárolnia egy változóban, és át kell adnia azt a változót, hogy ugyanarra a szimbólumra hivatkozzon.

a valueOf példában észreveheti a problémát, ha nem vagyunk óvatosak vagy tudatában. Mivel a valueOf egy string tulajdonság (mint a emp3) , bárki felülbírálhatja véletlenül, vagy valaki, aki nem tud róla valueOf tervezheti, hogy saját használatra használja azt, gondolva, hogy “mi az, ami nem a nevében?”.

mivel a szimbólumok objektumkulcsként is használhatók, a JavaScript biztosított néhány globális szimbólumot, amelyeket objektumkulcsként kell használni néhány szabványos JavaScript művelethez. Mivel ezek a szimbólumok jól ismertek a fejlesztő számára, ezeket “jól ismert szimbólumoknak”nevezik. Ezek a jól ismert szimbólumok a Symbol funkció statikus tulajdonságaiként vannak kitéve a nyilvánosságnak.

az egyik jól ismert szimbólum a Symbol.toPrimitive amelyet az objektum kulcsaként kell használni annak primitív értékének megszerzéséhez. Igen, jól gondolkodsz, ez a valueOf metódus helyettesítése, és előnyös.

(bevezetés/szimbólum-toprimitív.js)

a toPrimitive a módszer nem csak az objektum számértékét adja vissza. Kérjük, olvassa el a szimbólumok tanulságait, hogy többet tudjon meg róla.

a JavaScript számos ilyen jól ismert szimbólumot tartalmaz az objektumok alapértelmezett JavaScript viselkedésének elfogására és módosítására. Erről és a szimbólumokról általában a szimbólumok leckében fogunk beszélni.