Encapsulation in JavaScript

ez lesz az utolsó bejegyzésem a “JavaScript for (C/)al Developers” sorozatban. Ha folytattam a blogolást szinte tiszta JavaScript cuccokról, ésszerűen megkérdezheti, hogy ez valójában NAV blog vagy JavaScript. Ez még mindig NAV, és bár a cucc, amiről írni fogok, tisztán JavaScript koncepció, nagyon fontosnak tartom minden vezérlő bővítmény fejlesztő számára. Szóval, fogd meg a sörömet, és várjál még egyet.

az egyik panasz, amelyet gyakran hallok a JavaScript-ről, az, hogy a JavaScript-ben nincs beágyazódás. Ez szinte teljesen igaz, kivéve azt a tényt, hogy teljesen hamis.

hol van a probléma az első helyen, majd mi a megoldás? Merüljünk bele.

a probléma

képzelje el, hogy konstruktort deklarál. Képzelje el egy pillanatra, hogy az ES5 world-ben vagyunk (amit sajnos használnunk kell, ha azt akarjuk, hogy a vezérlő bővítményeink teljes mértékben kompatibilisek legyenek minden olyan platformon, amelyen mind a NAV, mind a Business Central támogatott).

ez az én kódom:

magától értetődően, ez azt mutatja 42, ami a jelenlegi korom.

hamarosan születésnapom lesz, tehát ez megmutatná 43:

most, bár én nagyon szeretem, hogy képes legyen valami ilyesmi a való életben:

… ez nem fog megtörténni. Egy tisztességes objektum-orientált világban az ” age ” – nek kapszulázott tulajdonságnak kell lennie, és nem szabad tudni hívni a vjeko-t.életkor = 25 egyáltalán. A C# és a” normál ” objektum-orientált nyelvek rendelkeznek a kapszulázás fogalmával, ezt privát mezőkkel tudják kezelni, de a JavaScript-nek nincs privát fogalma. Bármi, amit ezen definiálnak az objektumkonstruktoron belül (vagy később egy épített objektum példányán), teljes mértékben elérhető minden olyan kód számára, amely hozzáfér az adott példányhoz. A fenti példámban bárki beállíthatja az életkorot és megúszhatja.

mondhatjuk, hogy a JavaScript nem rendelkezik kapszulázással. És ahogy fentebb mondtam, teljesen tévedsz.

a megoldás

bármennyire is nyilvánvaló, hogy semmit sem deklarálhatunk közvetlenül privátnak, még mindig vannak dolgok, amelyeket használhatunk. Az egyik szép koncepció, amely jól jön, az úgynevezett bezárások. A bezárásokat hosszasan magyarázzák egy millió blogon, dokumentációs webhelyen és kódpéldán az egész interneten, és a saját tempójában google-t kereshet belőlük, így itt nem fogok belemerülni a bezárások magyarázatába. Én egyszerűen ugrik jobbra alkalmazása őket, hogy megoldja a kapszulázási probléma.

van legalább két módon, hogyan lehetne kezelni ezt. Először tegyük meg a nyilvánvalóbbat: egy hozzáférési funkciót.

képzelje el a világot tulajdonságok nélkül, ahol nem tehet tárgyat.tulajdonság = érték (mint vjeko.age = 25 a mi esetünkben, annyira, mint én teljesen szeretem!). Abban a világban getter és szetter funkciók lennének:

(egy pillanatra hagyja figyelmen kívül azt a tényt, hogy még mindig ezt használom.”tulajdonság”)

nyilvánvaló, hogy ezeket így hívhatja:

akkor, ha azt akarta, hogy az életkor csak olvasható legyen, egyszerűen eldobja a setAge szetter funkciót. Ha ez.az életkor valóban privát volt (ami nem az), ez megteszi a trükköt az Ön számára. A probléma az, hogy ezen semmi sem privát, bárki számára elérhető, aki hozzáfér az objektum bármely példányához. Annyira nyilvános, amennyire csak lehet.

a probléma megoldásához először a getter függvény deklarációját kell áthelyeznünk a prototípusról a példányra. A prototípus tagok a legközelebb állnak ahhoz, amit statikusnak neveznénk a C# – ban, annak ellenére, hogy futásidőben mind a statikus, mind a példány tagjai bizonyos viselkedési tulajdonságokkal rendelkeznek. Először azonban tegyük el a tagot a prototípustól, majd a példányra:

ez csak a probléma első részét oldja meg, azt a tényt, hogy a getAge-t a prototípuson határozták meg, nem pedig a példányon. Egy ilyen egyszerű változtatással azonban:

… teljesen megoldjuk a problémát:

az életkor most teljesen be van zárva. A getter funkción keresztül érheti el, de közvetlenül nem állíthatja be, mert csak a This bezárási hatókörében érhető el.getAge példány funkció.

a Person osztály teljes megvalósításához át kell helyeznie a growOlder függvényt a prototípusból a példányba:

ez pedig pontosan úgy működik, ahogy szeretné, hogy működjön:

de miért működik? A bezárások miatt működik. A konstruktor age paraméterét mind a getAge, mind a growOlder funkciók bezárási hatókörében rögzítették, lehetővé téve az értékének elérését mindkét funkcióból, de teljesen elérhetetlenné téve bárki más számára, bárhol máshol.

még jobb megoldás

mondhatnánk, hogy nem akarjuk elérni egy getter függvény, és hogy szükség van a teljes értékű írásvédett tulajdonság szintaxis. Azt szeretné, hogy a kor csak olvasható és kapszulázott ugyanabban az időben. Megvagy! A JavaScript ezt nem tudja beágyazni! Kivéve, hogy abszolút képes.

foglalkoztam az objektummal.defineProperty módszer az én előző post, és ha elolvassa, hogy az egyik, akkor azonnal látni, hogyan lehet alkalmazni itt.

tehát definiáljuk a person osztály csak olvasható példány tulajdonságát:

ott. Nem fájt. És működik:

szóval itt van. Teljes körű beágyazása JavaScript, hogy segítsen írni jó, elszigetelt kódot, és hogy a control bővítmények valódi kick-a$$ szinten.

Boldog JavaScripting, és remélem, hogy több időt, hogy a blog más jó és hasznos JavaScript tippek és trükkök (C/)al Fejlesztők.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.