Egy JavaScript keretrendszer születése – natív osztályok
Nemrég tett közzé Farkas Máté (fmate14) blogbejegyzést tömb bejárási problémákról, amelyhez kapcsolódóan Galiba Péter (Poetro) szóba hozta, hogy létezik egy hasOwnProperty()
nevű Object
metódus. Kicsit jobban utánajártam, és kiderült, hogy MSIE nem támogatja, a többi nagyobb böngésző viselkedése pedig néhány esetben eltérő, ezért úgy döntöttem, hogy egy az egyben felülírom ezt a metódust.
Object.hasOwnProperty
A sorozatban megjelent
- Egy JavaScript keretrendszer születése – bevezetés
- Egy JavaScript keretrendszer születése – natív osztályok
- Egy JavaScript keretrendszer születése – öröklődés
A bevezetőben isKey()
lokális függvény volt, amiből most Object.hasOwnProperty()
lesz. Igazából ez Object.prototype.hasOwnProperty()
, de a prototype
-ot nem teszem ki, mert statikus metódusokat (osztályfüggvényeket) sem most, sem a későbbiekben nem fogok használni. Ennek az az oka, hogy a statikus metódusok ugyanott kapnának helyett, mint az osztályokra jellemző metódusok. Például: a statikus Array.append()
felülírná a ClassBuilder.classMethods.append()
-et az Array
osztályban. Persze az Array
még nem igazi – csak natív – osztály, de a fejezet végére már az lesz.
Object.prototype.hasOwnProperty=function (k)
{
var p=this.constructor.prototype;
return (k in this) && (!(k in p) || p[k]!==this[k]);
};
Object.prototype.getClass=function ()
{
return this.constructor;
};
Mint látható, bekerült még az Object.getClass()
, ami a konstruktort adja vissza. Ez azért volt szükséges, mert már osztályokról és nem konstruktorokról beszélünk.
Az isKey(o,i)
helyett pedig mindenhol áttértünk a o.hasOwnProperty(i)
-re. Ha összehasonlítjuk a két függvényt, akkor látható, hogy nem teljesen ugyanazt csinálják. Az isKey()
csak az Object.prototype
tulajdonságait szűri az objektumokból, a hasOwnProperty()
pedig az aktuális osztály prototípusának a tulajdonságait is. Ez utóbbiba beletartoznak az Object.prototype
tulajdonságai is, hiszen a prototípusok is objektumok, tehát megkapják ezeket. Ennek a viselkedésnek az a következménye, hogy a ClassBuilder.clearFunctionMethods()
egyszerűsödik:
clearFunctionMethods: function ()
{
for (var j in Function.prototype)
{
if (Function.prototype.hasOwnProperty(j))
{
this.current[j]=undefined;
}
}
},
Mindent a maga idejében
A megvalósításnál elkövettem egy lényeges hibát.
Mivel egy bonyolult dolgot építünk fel, ezért a builder pattern a célravezető. A buildert indokolja az is, hogy vannak natív osztályok, melyekhez később szintén hozzá kell adni az osztályokra jellemző viselkedést.
Itt a hiba nem feltétlen a builder pattern használata volt, hanem amivel megindokoltam. Az indoklásnál arról beszéltem, hogy a későbbiekben valamikor natív osztályokhoz is hozzáadjuk a Class
viselkedést. Ez rendben is van, viszont még egyáltalán nem volt szó arról, hogy ezt hogyan oldjuk meg. Szóval egy olyan dologgal indokoltam a mintát, ami valamikor a jövőben esedékes csak, és ki tudja mikor… Ilyen esetben általában igaz, hogy úgy kell megvalósítani a dolgokat, ahogy a mostani helyzet indokolja, ha pedig majd a jövőbeni dolgokat hozzá kell adni a rendszerhez, akkor ott és akkor refaktorálni kell. Így egy csomó felesleges kódot és agyalást megspórolhatunk.
Úgy döntöttem, hogy a director kódot (ez vezérli a buildert) a Class()
függvényből átteszem a ClassBuilder
be, így gyakorlatilag egy factory jön létre.
var ClassFactory=
{
classMethods:
{
append: function (o){/* ... */}
},
createClass: function ()
{
this.newClass();
this.clearFunctionMethods();
this.addClassMethods();
return this.getResult();
},
newClass: function (){/* ... */},
clearFunctionMethods: function (){/* ... */},
addClassMethods: function (){/* ... */},
getResult: function (){/* ... */}
};
var Class=function (o)
{
if (this.constructor!==arguments.callee)
{
throw new SyntaxError("class=new Class(...) is the right syntax");
}
return ClassFactory.createClass().append(o);
};
Majd ha később tényleg kiválik a director, akkor visszanevezem ClassBuilder
re.
Osztály leválasztása a függvényekről
Az osztályok még nem teljesen különültek el a függvényektől, szóval fejezzük be ezt a folyamatot. Az append()
-nél egyelőre megengedjük, hogy osztály is bekerüljön a tulajdonságok közé. Ezen változtatni kell. Először írjuk át az osztályok constructor
tulajdonságát. Lehet gondolkodni azon, hogy ezt hol tegyük meg a ClassFactory
ben. Én úgy gondoltam, hogy az addClassMethods()
elejére nyugodtan be lehet tenni ezt is. Viszont így már az addClassMethods()
elnevezés nem teljesen fedi a valóságot, hiszen nem csak metódusokat adunk az osztályhoz. Szóval átírtam implementClassInterface()
-re, és új nevet kapott a clearFunctionMethods()
is, hogy az előbbivel összecsengjen.
createClass: function ()
{
this.newClass();
this.removeFunctionInterface();
this.implementClassInterface();
return this.getResult();
},
/* ... */
removeFunctionInterface: function ()
{
for (var j in Function.prototype)
{
if (Function.prototype.hasOwnProperty(j))
{
this.current[j]=undefined;
}
}
},
implementClassInterface: function ()
{
this.current.constructor=Class;
for (var j in this.classMethods)
{
if (this.classMethods.hasOwnProperty(j))
{
this.current[j]=this.classMethods[j];
}
}
},
Ezek után az append()
-et bővítettem ki az osztályokat ellenőrző kóddal.
append: function (o)
{
if (!o)
{
return this;
}
for (var j in o)
{
if (!o.hasOwnProperty(j))
{
continue;
}
var v=o[j];
if ((v instanceof Function) && v.constructor===Class)
{
throw new TypeError("Class property cannot be a Class.");
}
this.prototype[j]=v;
}
return this;
}
Natív osztályok
Most már nekiállhatunk a natív osztályoknak. Mit is kell velük csinálni? Mivel a natív kódba nem nyúlhatunk bele, annyit tehetünk, hogy töröljük a függvényekre jellemző felületet, és hozzáadjuk az osztályokra jellemzőt. Durvább beavatkozást nem érdemes csinálni.
Elsőnek bővítsük a bevezetőben létrehozott tesztünket:
test("native classes",function ()
{
ok(Array.getClass()===Class,"Constructor ok.");
ok(Array.call===undefined,"Function interface removed.");
ok(!!Array.append,"Class interface implemented.");
});
Mivel a ClassFactory
ben a dolgok nagy része már megvan, ezért nyilvánvaló, hogy a natív osztályra vonatkozó kód is ide fog kerülni. Csak módot kell adni a this.current
natív osztályra való átállítására, a többi már megvan. Erre a célra hozzuk létre a ClassFactory.setClass()
metódust.
setClass: function (current)
{
this.current=current;
},
Ezután már csak le kell vezérelni a létrehozási (módosítási) folyamatot.
nativeClass: function (nativeClass)
{
this.setClass(nativeClass);
this.removeFunctionInterface();
this.implementClassInterface();
return this.getResult();
}
Factory szétbontása
Most van az a rész, ahol el kell gondolkodni, hogy szétbontsam-e újra a ClassFactory
t. Végül úgy döntöttem, hogy az átláthatóság kedvéért megteszem, így kiemeltem a nativeClass()
és createClass()
metódusokat, ezek lettek a ClassFactory
, a maradék pedig a ClassBuilder
. A ClassFactory
most így néz ki:
var ClassFactory=
{
createClass: function ()
{
ClassBuilder.newClass();
ClassBuilder.removeFunctionInterface();
ClassBuilder.implementClassInterface();
return ClassBuilder.getResult();
},
nativeClass: function (nativeClass)
{
ClassBuilder.setClass(nativeClass);
ClassBuilder.removeFunctionInterface();
ClassBuilder.implementClassInterface();
return ClassBuilder.getResult();
}
};
Látható, hogy elég sok az ismétlődés, amit emeljünk ki külön metódusba.
var ClassFactory=
{
createClass: function ()
{
ClassBuilder.newClass();
return this.getResult();
},
nativeClass: function (nativeClass)
{
ClassBuilder.setClass(nativeClass);
return this.getResult();
},
getResult: function ()
{
ClassBuilder.removeFunctionInterface();
ClassBuilder.implementClassInterface();
return ClassBuilder.getResult();
}
};
Kész is. Így már átlátható, hogy mi vezérli a létrehozást (ClassFactory
) és foglalkozik annak részfolyamataival (ClassBuilder
).
Natív osztályok átformálása
Most szedjük össze a natív osztályokat, és végezzük el mindre a módosításokat. Nincs mi alapján kiválasztani a globális névtérből, hogy mi natív osztály, és mi nem, szóval jobb, ha csinálunk egy listát róluk.
var nativeClasses=
[
Boolean,
Number,
String,
Array,
RegExp,
Date,
Error,
TypeError,
ReferenceError,
RangeError,
SyntaxError,
EvalError,
URIError,
Object,
Function,
Class
];
for (var j=0,l=nativeClasses.length; j<l; ++j)
{
var nativeClass=nativeClasses[j];
ClassFactory.nativeClass(nativeClass);
}
Igen, a Class
is közéjük került. Esetleg el lehet gondolkozni azon, hogy a ClassFactory.classMethods
-ból áttegyük a dolgokat a Class.prototype
-ba, így az osztályok tulajdonságai is bővíthetőek lennének az append()
használatával.
Egyelőre futtassuk a tesztet. Hoppá, jelez, hogy gond van: SyntaxError (Function interface removed.). Ha alaposabban megnézzük a removeFunctionInterface()
-t, akkor hamar kiderül, hogy a for-in nem megy végig a natív metódusokon, így kénytelenek vagyunk kézzel felülírni őket. Szimplán a delete()
nem lenne elég, mert a Function.prototype
-ból jönnek ezek a dolgok.
removeFunctionInterface: function ()
{
this.current.apply=undefined;
this.current.call=undefined;
this.current.toString=undefined;
this.current.toSource=undefined;
this.current.valueOf=undefined;
for (var j in Function.prototype)
{
if (Function.prototype.hasOwnProperty(j))
{
this.current[j]=undefined;
}
}
},
Csinálhatnánk tömböt is ezeknek a tulajdonságoknak, de én úgy gondoltam, hogy annyira azért nincs sok belőlük.
Futtassuk a tesztet ismét. Minden okés.
Class.prototype
Na, most fontoljuk meg a classMethods
áthelyezését. Ehhez módosítani kell az implementClassInterface()
-t,
implementClassInterface: function ()
{
this.current.constructor=Class;
for (var j in Class.prototype)
{
if (Class.prototype.hasOwnProperty(i))
{
this.current[j]=Class.prototype[j];
}
}
},
és áttenni az append()
-et.
Class.prototype=
{
append: function (o){/* ... */}
};
Futtassuk a tesztet. Hamar kiderül, hogy itt is gond van: SyntaxError (class=new Class(...) is the right syntax). Ez azért van, mert a Class.prototype.constructor
most az Object
, mert egy objektumot adtunk meg prototípusnak. A Class
példányok pedig ezt a viselkedést öröklik, és ezért elhasal a szintaxis ellenőrzőnk.
var Class=function (o)
{
if (this.constructor!==arguments.callee)
{
throw new SyntaxError("class=new Class(...) is the right syntax");
}
return ClassFactory.createClass().append(o);
};
Ugye ilyenkor az arguments.callee
a Class
, a this.constructor
pedig az Object
. Ha átállítjuk a konstruktort Class
ra, akkor pedig a implementClassInterface()
-ben a hasOwnProperty()
nem fog átengedni egyetlen tulajdonságot sem, hiszen a Class.prototype
-ot hasonlítja majd össze saját magával.
Én úgy döntöttem, hogy a gordiuszi csomó kibogozása helyett inkább átvágom azt. Szerintem a new Class(/* ... */)
szintaxis megőrzése nem annyira fontos, szóval nem kezdtem áthidaló megoldás gyártásába, hanem inkább töröltem a szintaxist ellenőrző kódot. Veszteni nem vesztettem vele semmit, hiszen az osztályok építését a ClassFactory
vezérli, a Class()
függvényben pedig sehol máshol nem kerül elő a this
kulcsszó.
var Class=function (o)
{
return ClassFactory.createClass().append(o);
};
Így most már meg lehet hívni függvényként is a Class
t, kinek ahogy tetszik.
pici helyesbítés
ClassFactory
elnevezés megtévesztő lehet, igazábólClassDiretor
-nak akartam elnevezni azért, hogy jelezzem, hogy az a gyártónak a rendező/vezérlő része. Én legalábbis úgy értelmeztem a builder patternt, hogy többek között ez a szétválasztás, ami fontos benne. Ha lehetne (szépen) örököltetni, akkor valószínűleg más lenne az egész szerkezete.hasOwnProperty
hasOwnProperty
legalábbis Object esetén. Így:hasOwnProperty
-tIgaz.
Én itt néztem, aztán ebből következtettem arra, hogy biztos azért tol
Ha
Object.prototype
viszi, akkorFunction.prototype
-al sem lesz gond, csak az olyanoknál, mint awindow,document,dom nodek...
, mert ie valamiért nemObject
-ből származtatja ezeket....(Ezt ie8-ra mondom, nem tudom a régebbi verziókban hogy van.)
Mondjuk sok fennakadást nem okoz a dolog, mert dom-nál úgysem használna ilyet az ember. Ahogy nézem a NodeList sem örökli, szóval azt is csak mint tömböt lehet iterálni.
ECMAScript-262 revision 3-ban adták hozzá a
hasOwnProperty
-t a szabványhoz 1999-ben, a safari implementálta utolsóként a nagyobb böngészők közül (2005 végén), és ahogy nézem a többi alkalmazás is támogatja már.Ha valaki használ olyan alkalmazást, ami nem támogatja, akkor kérem szóljon, addig is törlöm a kódból githubon, a cikkben meg eldöntjük mi lesz.
Kösz, hogy szóltál.
Kérdés
Szóval villanyosítsatok föl légyszi, hogy miért lesz ettől valakinek jobb az élete (hacsak nem azért, hogy a máshonnan ismert mintákat szuszakolja bele a JS-be).
Az alap rendszert nem
Túl nagy
Hát nem is tudom igazán, hogy
Leírom ide, hogy mik lesznek, és döntsétek el ti, hogy folytassam e a rendszer bemutatását, vagy nincs rá érdeklődés. Azt hiszem érthető, hogy azt a kevés szabadidőmet nem szívesen fordítom olyan cikkek írására, amiket senki sem olvas.
csomagok, típusellenőrzés alap:
getName()
-el...Kérlek írjátok meg, hogy van e érdeklődés rá, vagy nincs.
Én teljesen egyet értek
Olyan mintha Sopronba akarnék utazni Bp.-ről és mindezt Debrecenen keresztül tenném.
A js-ben nincsenek osztályok! Az hogy csinálunk egy Class-t attól még nem lesznek.
Valahol az első cikkben ez van:
és utána egy példa. Hát nem tudom. Szerintem próbáld ki:
később több bajt okozhat, úgyhogy én csinnyán bánnék vele. Főleg a Object-re gondolok itt.
Ha írsz egy jó bonyolult keretrendszert, és szerintem oda tartasz, akkor a végén már nem js-ben kell programozz, hanem abban a keretrendszerben, aminek már szinte, csak annyi a köze a js-hez, hogy abban íródott. Főleg akkor nem a legjobb dolog ez, ha böngészőben szeretnéd használni. Szerintem minden programozási nyelvnek megvan a sajátossága, szépsége. A js-nek is. Én nem akarom úgy érezni magam mikor js-ben programozok, mintha c-ben vagy éppen python-ban tenném... Ameddig most eljutott a keretrendszer, ha jól látom, ezt küszöböli ki:
Válaszok:
Ezt én értem, de mivel az osztályok viselkedését próbálom modellezni a konstruktorokkal, ezért szerintem jogosan nevezhetem őket osztálynak, még ha nem is azok. Nyilván az ember egy konstruktort arra használ, hogy példányosítson vele, tehát arra, amire osztályokat is használna. A függvényeket viszont függvénynek használjuk, és nem példányosításra. Azért csináltam ezt a
new Class(...)
rendszert, hogy ez teljesen egyértelmű legyen a kódból is.Több célom is van ezzel a keretrendszerrel.
később több bajt okozhat, úgyhogy én csinnyán bánnék vele. Főleg a Object-re gondolok itt.
Mire gondolsz? :-)
Szándékosan nem osztottam meg, hogy milyen funkciókkal bővítem az alap javascriptet, úgy gondoltam, hogy elég unalmas lenne, ha a cikksorozat elején felsorolnám a bővítések listáját, utána meg egyenként megvalósítanám a részeket. Github-on tákolok egy dokumentációt a rendszerhez, ott fent lesz minden előbb, vagy utóbb, sőt azt hiszem, hogy most kiteszem, hogy még mi várható, aztán eldönthetitek, hogy kíváncsiak vagytok e rá, vagy sem.
Kicsit hasonló OO
Szerintem ezzel az a probléma, hogy a kliens oldalon XML Schema implementációra lenne szükség. Tudomásom szerint ezt csak az IE nyújtja teljeskörűen egy browserben, bár a jelenlegi állkapotokat már nem ismerem XML Schema terén. A Mozilla úgyan megvalósított valamilyen egyszerűsített SOAP implemetációt, igazából nem tudom most hogy állnak ... Én végül hosszas töprengés után megmaradtam a kliens oldalon egy egyszerűsített XML-RPC megvalósításánál (well-formed, XML szerkezet validáció, típusellenőrzés viszont elsumkálova).
Igazából mindezzel azt szeretném csak mondani, hogy igen nagy fába vágtad a fejszédet ami mindig is elismerést vált ki belölem. Ha időd engedi folytasd bár Én sem vagyok időmilliomos ...
A kliens oldalon van XSLT
Ha megvan, hogy XSD-ből milyen js kód legyen, akkor utána meg lehet oldani JSON-al is az adatátvitelt, ami ugye sokkal tömörebb forma, mint egy soapEnv.
Amit szeretnék az az, hogy a validálás szerver és kliens oldalon egy forrásból menjen, tehát ne legyen redundáns (ne kelljen szerver és kliens oldalon ugyanazt az ellenőrző kódot kézzel megírni), mert az hibákhoz vezet.
(Amúgy ha xforms támogatott lenne a böngészőkben, akkor egy percet nem foglalkoznék tovább ezzel.)
Úgy gondolom ezt meg lehet
De az XML Schema-t az XML file validációjára szerettem volna használni. Ez a lépés a cross-browser támogatás miatt átalakult az esetemben egy XML struktúra és típus / érték ellenőrzést megvalósító javascript eljárásra a kliens oldalon. Nyilván szebb lenne, ha a böngészőnek küldött xml és a kapcsolódó xsd file segítségével ezt a validációt a böngésző végezné.
Szerintem is.
Persze, én is szeretném, ha több dologra lenne már beépített lehetőség, de sajnos nincs :S és az ez irányú fejlesztések is nagyon lassan haladnak...
Úgy gondolom ezt meg lehet
De az XML Schema-t az XML file validációjára szerettem volna használni. Ez a lépés a cross-browser támogatás miatt átalakult az esetemben egy XML struktúra és típus / érték ellenőrzést megvalósító javascript eljárásra a kliens oldalon. Nyilván szebb lenne, ha a böngészőnek küldött xml és a kapcsolódó xsd file segítségével ezt a validációt a böngésző végezné.
SOAP
Szimplán annyi, hogy van egy
Hogy ez mennyire lenne gyors vagy lassú, arról jelenleg fogalmam sincs, pont ezért kéne kipróbálni. A teljes view így statikus formában jönne, szóval a sablonozás terhe lejönne a szerverről. Az adatátvitel érdekesebb kérdés, egyrészt a statikus tartalmat lehet böngészőben kesselni, másrészt a javascript motornak egy xsl fájlt csak egyszer kell leszednie, nem pedig minden oldal generálásakor, viszont a soapEnv nem valami tömör forma (nyilván indent nélkül egy fokkal jobb), de mégsem egy JSON. Azt hiszem netes adatátvitelnél az lenne a jó, ha megcsinálnák a SOAP JSON-os megfelelőjét.
Nem véletlen
Szerinted mi az oka ennek?
Struktúra
Egy JSON tömböt sokkal egyszerűbb parzolni és validálni is, sokkal kisebb az esélye, hogy hibát vétesz benne és gyorsabb is. Gyakorlatilag az összes webes nyelv (ActionScript kivételével, ami legendásan feature-szegény) implementálja a JSON-t, amíg a SOAP-ot értelmesen alig.
Hogy még egy harmadik dolgot mondjak, SOAP-ból az ember legtöbbször kódot generál, amit aztán nem szívesen módosít. A webes API-k kicsit gyorsabban változnak, bővülnek, ezért talán könnyebb JSON-ban valamit alkotni, mint egy UML eszközzel nekiesni, mert talán ágyúval verébre és a konkurencia már háromszor megcsinálta, mire az első verzió kijön. Szép a módszertanilag korrekt és alapos fejlesztés, de a webes világ nem ebbe az irányba megy. (Nézd csak meg, a Facebook hányszor rohad le, mégis mindenki meg van őrülve, hogy arra fejleszthet.)
Ezek nyilván itt csak hevenyészve összecsapott érvek, de valamiért a fejlesztői társadalom célszerűbbnek látta a viszonylag egyszerű webfelületekhez JSON-t használni.
Ennél árnyaltabb lehet a kép
(Nem fejlesztettem benne még soha, de gondolom mivel SOAPot ms találta ki, ezért csak össze tudtak hozni egy használható kliens osztályt silverlight-hoz.)
Nekem az a benyomásom erről az egész soap dologról, hogy az olyan divatnyelvek, mint a flash-actionscript vagy a php továbbra is a gagyit támogatják a már kidolgozott szabványok helyett. Végül úgyis ugyanoda fognak eljutni, mint amit soap tud, csak xml alapok helyett json-nal (pl: xml schema helyett lesz ill. már van json schema, stb...). Ennek örülök is, meg nem is. Azért örülök, mert szeretem a javascriptet, és nyilván azért nem, mert minek valamit kétszer feltalálni?
Java-t nem régóta tanulom, viszont én úgy tudom, hogy ott nem wsdl-ből lesz a kód, hanem annotációkkal adják meg, hogy mi menjen ki webservice-be, aztán ezek alapján generálják a wsdl fájlt. (Amúgy egy darabig én is az uml->wsdl->php,js módon akartam kódot generáltatni, de pont emiatt a nehéz módosíthatóság miatt vetettem el az ötletet, meg mert lusta voltam megírni az XSLT-ket hozzá :P)
Találtam egy az én
http://www.tonymarston.net/php-mysql/model-view-controller.html
(Nem olvastam még el, csak belepörgettem.)
Én annyit módosítanék az ő változatán, hogy kitenném kliens oldalra az XSL transzformációt, szerver oldalon pedig a Controller az WebService lenne.
Hogy ne csak beszéljek. Egy
Tuladonképpen xml üzeneteket cserél a böngésző és a szerver. Az XML-ben kapott információt megjeleníti a javascript a böngészőben. Ebből hiányzik még az OO ...
Persze, küldd, majd átnézem
Érdekes a kódod, teljesen
Szándékosan nincs benne OO.
Általad és általam is hiányolt OO implemetáció idő hiányában elmaradt. Ezért is olvasom a cikksorozatodat, hátha okosabb leszek ...
Nem terveztem a kódban található megjegyzésekből dokumentáció gyártását (egyedi kulcsszavak és jelölések vannak a kommentekben, no meg ECMA / W3C szabványrészletek) mivel tanulási célú tech demoról van szó. A dokumentálás formátuma a Java programozás miatt rámragadt "rossz szokás". Ha esetleg ilyesmit keresel a YUI csinált JavaScriptre egy a Javadoc-hoz hasonló rendszert:
Köszi, megnézem, bár lehet,
Elnézést, hogy csak most
És ez így is van. A js-nek van egy olyan sajátossága, hogy egy függvény lehet függvény és konstruktor is. Előző hozzászólásom: Class() vs new Class(). Az előbbi függvényhívás és a visszatárási érték a függvény visszatérési értéke. Míg a második esetben a függvény konstruktorként funkcionál és a visszatérési érték, függetlenül attól, hogy a függvénynek (ez esetben konstruktornak) van-e visszatérési érték beállítva, egy új objektum, mely a prototype-ból örökli a tulajdonságait.
Mint ahogy írtam is: Főleg a Object-re
Azzal kezdted a cikket, hogy a kiegészítetted az Object-et: Object.prototype.hasOwnProperty, Object.prototype.getClass
Én sajnálom! Engem minden unalmas részlet érdekel. :)
Valamelyik, valakinek írt válaszodból nekem az jött át, hogy az a néhány, a cikkel nem mindenben egyetértő hozzászólás letörte a lelkesedésedet és abba kívánod hagyni. Szerintem ne tedd:
1. Amit én írok az az én teljesen szubjektív véleményem.
2. Mint ahogy valaki írta is: van rá igény, hiszen mennyi hozzászólás született...
3. Én személy szerint örülök, hogy a itt ilyen cikk is van. Olyan ami egy technológia határait feszegeti.
Míg a második esetben a
Ez így nem igaz. A konstruktor hívásakor minden esetben létrejön egy új objektum, de ha beállítjuk a visszatérő értéket, akkor nem ezt az objektumot fogjuk kapni. Alapból annyi van js motorban, hogy ha
undefined
a visszatérő érték, akkor azt állítsa átthis
-re. Végülis ez is automatizálás valamennyire, hogy ne kelljen kiírni a konstruktorokban, hogyreturn this
.Ezzel persze lehet vitatkozni, de ha kötelezően az új példányt kellene megkapni, akkor letiltották volna a
return
használatát a konstruktorokban.Nem az
Object
volt a kérdés, hanem, hogy milyen problémákat okozhat, ha belenyúlok azObject.prototype
-ba? (egyébként még párszor meg fogom tenni :-) )Idővel megkapod őket. :-)
Nem csak azzal volt gond, hogy kicsit letört a lelkesedésem, inkább azzal, hogy sok a zh meg a szigorlat ebben a félévben, aztán nem tudom olyan ütemben folytatni a cikkírást, mint szerettem volna. Az első három cikket úgy írtam, hogy két hetente egy cikk, de ez már sajnos nem tartható. Valszeg ezentúl csak havonta vagy ritkábban fogok cikket írni, amíg vége nincs a félévnek.
Oké, nem teszem :-)
Szerintem te nagyon kevered a
Jogod van a véleményedhez,
Nos az van, hogy ezt a
Félreértés
Hát egyelőre mindenképp
Az a baj, hogy csomag, osztály, metódus nevek lekérését, beépített típusellenőrzést meg ilyesmiket lehetetlen modulárisan megoldani. Mindenképp kell egy rendszer, ami ezeket menedzseli.
Mondok egy példát (az eddig vázoltakhoz képest még jobban bővített rendszerre). Vannak ezek az osztályok (lenti kód), a Bean azt jelenti, hogy a types-ban megadott dolgokra automatikusan létrehoz setter és getter metódusokat. A Collections.List olyasmi, mint a java collections framework List-je, ha beállítom az element típusát Car-ra, akkor csak kocsikat fogad el a lista. (Agyaltam azon, hogy hogyan lehetne új osztály (CarList) létrehozása nélkül megadni a listában szereplő típust, de még nem jutottam semmire...)
Az, hogy túlzottan nagy a rendszer js-hez más kérdés. Én úgy gondolom, hogy megéri, mert sokkal gyorsabban lehet fejleszteni egy ilyen rendszerben, mint core javascriptben, vagy minimálisan kibővített javascriptben, továbbá az automatizálásnak még megvan az az előnye is, hogy csökkenti a hibázási lehetőségek számát.
Sebességben nem feltétlen annyira jók ezek a megoldások, mint egyszerűbb keretrendszereknél, de ha az én 7 éves gépem gond nélkül viszi őket, akkor szerintem máshol sem fognak gondot okozni. Ugye a javascript motorokat meg amúgy is egyre gyorsabbra csinálják a böngésző gyártók...
Csatlakozom
Rendben, akkor folytatom a
(Az öröklődéses részt most hétvégén átírom, az azt követő rész csak november elejére-közepére esedékes.)