Típusos Javascript
Írtam egy nagyon egyszerű kódot a JavaScript típusossá tételére, és azt nem értem, hogy ez eddig miért nem jutott másnak is eszébe.
Function.prototype.typing = function () {
var method = this;
var Types = arguments;
return function () {
if (arguments.length != Types.length) {
throw 'Eltérő a paraméter szám...';
}
for (var i = 0, l = arguments.length; i < l; ++i) {
var param = arguments[i];
var Class = Types[i];
if (!(param instanceof Class)) {
var type = typeof(param);
if (type != 'object') {
if (
type == 'string' && Class == String
||
type == 'number' && Class == Number
||
type == 'boolean' && Class == Boolean
) {
continue;
}
}
if (param === null) {
continue;
}
throw 'Eltérő típus...';
}
}
return method.apply(this, arguments);
};
};
try {
(function (a, b, c) {}).typing(String, Number, RegExp)('a', 123, /test/g);
(function (a, b, c) {}).typing(String, Number, RegExp)('a', null, /test/g);
(function (a, b, c) {}).typing(String, Function, RegExp)('a', function () {}, /test/g);
alert('jó');
} catch(e) {
alert('rossz');
}
Persze lehetne még variálni rajta, hogy ne a függvénytörzs után legyen a típus megadása, meg a natív metódusok typeof
bugját lekezelje, de nyilván csak bemutatónak szántam…
Jó
Még nem
A legtöbb függvénytárban
Nehéz kérdés
Nyilván nem csak a típusellenőrzésről van szó, hanem mondjuk a prototype.js-ben fordulnak elő még ilyenek, hogy bind, delay meg hasonlók. Úgy általánosságban be lehet így állítani a scope-ot, a scope bizonyos tulajdonságait ideiglenesen átírni, amíg a függvény fut, típusellenőrzést automatizálni stb..
Pl a típusellenőrzést ki lehetne terjeszteni akár DOM objektumokra is.
Leginkább a switch-eket, meg az olyan if-else kódrészeket szeretném helyettesíteni így, amikben csak a típusellenőrzésről van szó. Class.extends szimulálásánál pedig az ideiglenes scope tulajdonság átírás, ami használható, mert a this.parent az függ attól, hogy az adott függvényt melyik osztályban adtuk meg először. Nyilván annak a szülőjére vonatkozik a this.parent.
Itt például ha a this.parent a B.prototype-ra vonatkozna, akkor végtelen ciklusba kerülnénk, ezért ideiglenesen a this.parent-et át kell írni A.prototype-ba, amikor a B.initialize-t futtatja a rendszer.
Én is csak általánosságban
{ } jelek
{}
, de látom azóta javítva lettek.Hát..
JSLint barát változat
Köszi
Inkább…
Bármilyen felülettel lehet
Bármilyen felülettel meg lehet csinálni, az implementáció onnantól, hogy megvan a típusok tömbje, meg a metódus, ugyanaz lesz.
pl:
Csak nagyon egyszerűen valami ilyesmire gondolok:
Ahogy nézem javascript 2.0-ban vannak már osztályok, meg típusos nyelv lett, de többet sajnos nem találtam róla. Lehet, hogy csak álom maradt? Ti tudtok valamit róla?
Nem hiszem, hogy csak ott...
Nekem javascripttel az a tapasztalatom, hogy az ilyen closure-ozás nem szokott jelentősen lassítani, inkább a DOM függvények, meg az animációk, amik nagyon erőforrás igényesek...
Esetleg még olyan helyzetet el tudok képzelni, amikor mondjuk bejön kívülről (pl ajax) valamilyen típusú dolog, aztán try-catch-el döntöd el, hogy egy adott függvény lefusson rá, vagy sem.
Meg hát ha interface-eket akarsz betenni, akkor mondjuk egy ilyesmit el tudok képzelni beépített típusellenőrzéssel:
Érdemes még körbenézni a
Szerintem azzal, hogy csak typeof irányba vizsgáljuk a paramétereket sokkal kisebbet lépünk, mint amekkora lehetőség volna itt. Ahhoz, hogy valóban legyen ennek értelme szerintem inkább instaceof -val kellene vizsgálni, hogy miféle Objektumot kaptunk. Ekkor talán valóság közelibb (?) példákat kaphatunk.
Engem tényleg érdekelne, hogy valójában létezik-e olyan élesben használt példa, amikor erre szükség van. Hiába nézem az itteni példákat, a neten található példákat, egyiket sem tudom elképzelni, hogy ilyen esetben ezt használnám. :)
Ezt leszámítva persze érdekes elképzelés.
Szerintem azzal, hogy csak
Ha jobban megnézed: van benne instanceof, csak valamiért a string,number,boolean típusoknál nem ment azzal.
Körbenéztem, sok újat nem láttam. Próbáltam összehozni egy komolyabb rendszert osztályokkal meg interfacekkel, meg ilyesmivel, menni menne, csak most nincs rá egy hetem. :-) Nem is olyan egyszerű, mint amilyennek elsőre gondolja az ember, főleg ha már genericitás meg templatek is szóba kerülnek. Lehetne ilyen alapon egész keretrendszert írni, és szerintem nem is lenne rossz a fejlesztése, csak hát be vagyok táblázva augusztus végéig.
Még meglátom, lehet, hogy megírom valamikor a nyáron, aztán írok cikket róla, vagy csak kiteszem valahova. Egyelőre ha van szabadidőm, akkor inkább XML,XSLT,XSD,WSDL meg ilyesmik foglalkoztatnak, sokkal hasznosabbak, mint a javascriptes gányolás.
Végleges felület
A megoldás nem a legszebb, lehetett volna még osztály szintű konstruktorral megcsinálni, de úgy gondoltam zavaró lenne a több konstruktor egy osztályon belül, főleg, hogy osztályfüggvények egyáltalán nincsenek, helyettük inkább a Singletont fogom bevezetni és használni mindenhol. (Esetleg a nagyon B) terv a nagybetűs osztályfüggvények bevezetése.)
A típuskezelést összevontam osztály szintre a metódusoknál a paraméterek neve alapján nézi, hogy milyen típust kell kapnia. Így osztály szinten egy paraméter csak egyvalamit jelölhet. Ez növeli az átláthatóságot, másrészt meg minden típust csak egyszer kell megadni osztály szinten. A típusok továbbörökítése így nagyon szimpla.
Absztrakt metódusról egyelőre gondolkozom, ami már biztos az interfacekkel kapcsolatban, hogy implementáció is lesz bennük, nem csak absztrakt rész. Gondolkodtam rajta, hogy külön veszem a megvalósítást "Fragment"-ekbe, de aztán letettem róla. Nem sokszor, de azért előfordult, hogy több osztályból kellettek volna függvények, ezzel a módszerrel meg nagyjából megoldható a dolog. Persze lehetne többszörös öröklés is helyette, de akkor meg a típuskezelés lenne még annál is bonyolultabb...
A new Class mellett még a new Singleton is szerepelni fog valószínűleg... Egyelőre még nem tudom, hogy egyből példányosítom e, amint felépült az osztály... Valszeg nem, max akkor, ha abszolut nem használok konstruktoros dependency injection-t...
Egyelőre így áll a szitu, a megoldása egész egyszerű lesz sztem, egyedül a függvény paraméter listájának kiolvasása okozhat némi gondot, de ha jól emlékszem regexel megoldottam már valamikor.
Néhány függvény dekorálásos dologra szükség lehet osztályon kívül is, pl defer (elhalasztja a fgv futását), vagy ilyesmik, a legtöbbre viszont nem igazán. Nagyjából ezzel felülettel szerintem megoldható az a káosz meg gányolás, ami a javascriptes osztályok írásánál van.
Legkésőbb július elején lesz implementáció hozzá, megpróbálom majd csatolni, vagy kitenni új blog bejegyzésbe, hátha érdekel valakit.
Üdv!
contracts.coffee
köszönöm a segítséget, csak
igen, de...
Egyelőre még nem. Annyi a
pl:
Na most elég sokat agyaltam azon, hogy mi lenne az ideális módszer arra, hogy ezeket a függőségeket jelölni tudjam, de mégse szálljon el az egész rendszer, és ne is legyen túl bonyolult. A végén erre jutottam:
Most hétvégén össze tudok dobni egy nagyon alap rendszert, csomagokkal, osztályokkal, öröklődéssel, meg típusossággal. Szerintem néhány óra alatt megvan, mert az elemeit elég sokat használtam, már csak össze kell illeszteni őket...
Én nem ennyire bonyolult
Nekem csak annyi kéne, hogy a funkcióknak legyen változó szignatúrája típusokkal. Pl én a osztály gyártást beírtam a Function.prototype-be.
Jó, hát ez a konstruktorokra
Az öröklődést már megoldottam
az overload azt csinálná hogy a függvénynek adna egy form nevü tulajdonságot ha az még nem lenn, és ez a tulajdonság a Form nevű osztály egy példánya lenne ami globálisan nem elérhető, ezen az osztályon dolgozna a overload metódus, ennek az osztálynak lennének olyan metódusai hogy indexOf, call, addSignature, stb, és így azt hiszem meg lehetne oldani hogy a szignatúrák is vándoroljanak öröklödésnél.
Na hát ez a különbség ahhoz
A lényeg, hogy tömören és átláthatóan gyűjteményekkel lehet megadni dolgokat. Mondjuk egy js object vagy egy tömb egy gyűjtemény. A gyűjtemények elemeinél le lehet tárolni feldolgozással kapcsolatos utasításokat. Én ezeket a példámban a kulcsban tárolom, de természetesen az érték oldalon is megadhatóak. Ezután fogod a gyűjteményedet és végig mész minden elemén, és mindegyiket feldolgozod az utasítás szerint. A lényeg, hogy így nem kell a kódban könyékig turkálnod, mert azt elintézi neked a feldolgozó programod...
Ami neked idáig megvan
Az kicsit össze-vissza ahogy
Gyere skype-ra laszlo.janszky.
2006-ból