A Jáva testvérkéje: JavaScript

Tartalomjegyzék:

Hasonlóságok és különbségek
Mire jó az egész?
JavaScript programok
JavaScript és HTML
Adatok, változók és kifejezések
Utasítások
Objektumok
Beépített objektumok
Eseménykezelés
Érdekes trükkök
Kattintásra induló JavaScript függvény
Állapotsor kezelés
Új ablak nyitása
Mi lesz veled JavaScript?


Nagyjából a Jáva nyelv szélesebb körben ismertté válásával egy idôben SUN és Netscape közösen bejelentett egy másik, a Jávánál egyszerûbbnek szánt programozási technológiát, amely szorosan kötôdött a Netscape böngészôhöz. Ez a JavaScript-nek nevezett nyelv a HTML lapok írói számára készült, célja, hogy kevés munkával interaktív funkciókkal lehessen bôvíteni a HTML lapokat. Ily módon nem csak változatosabbá tehetjük a megjelenô információkat, de az ûrlapok (forms) kezelésénél a Web szervert is tehermentesíthetjük.

Hasonlóságok és különbségek

Rossz nyelvek szerint a Jáva és a JavaScript nyelvekben mindössze nevük elsô 4 betûje a közös - mellesleg a JavaScript-et kezdetben Mocha-nak, majd LiveScript-nek hívták de ha ez kissé túlzó állítás, de azért van benne valami. A két nyelvet külön-külön fejlesztgették, a fejlesztôk csak jóval késôn hallottak egymásról. Aztán egyszer csak a Sun és a Netscape egymásra talált és rájöttek arra, hogy ha már hasonló dolgokkal foglalkoznak, ne használjanak teljesen más neveket.

Ha a két gyereknek más-más papája is van, de azért vannak tagadhatatlan hasonlóságok. Például a szintaxisukat mindketten a C nyelvtôl örökölték, no meg a manapság oly divatos objektumorientáltságot egyikük sem kerülhette el. és persze közös a "lakhelyük" is, mind a Jáva programkák, mind a JavaScript parancsok futnak a Netscape böngészôn. Sôt jó hír a makacs, konzervatív Windows 3.11 felhasználóknak nem sértés, én is az vagyok , a JavaScript-et még a Windows-os böngészô is érti!

Nézzünk néhány különbséget részletesebben is:

Mire jó az egész?

A JavaScript programok leggyakoribb felhasználása az ûrlapokhoz kötôdik. A HTTP protokoll lehetôvé teszi, hogy a kitöltött ûrlapot elküldjük szerverre, ahol egy feldolgozó program indul (ún. CGI script) el és fogadja az információkat. Ez a program általában azzal kezdi a tevékenységét, hogy ellenôrzi a kapott paramétereket és hiba esetén visszaküld valamit a böngészô elôtt ülô felhasználónak. Ám ez felesleges hálózati terhelést jelent, a feldolgozó program is potyára indult el. Egy kis JavaScript program segíthet a dolgon, elküldés elôtt de akár az egyes mezôk kitöltésekor még a böngészôben ellenôrizheti, hogy megfelelô adatokat adtunk meg, figyelmeztethet, korrigálhat, ha kell.

A JavaScript felhasználható arra is, hogy a megjelenô HTML lapot vagy annak részeit dinamikusan, a felhasználó környezetének, általa megadott információknak megfelelôen állítsuk elô. A programból létrehozott HTML formátumú szöveget a böngészô ugyanúgy jeleníti meg, mintha az a szerverrôl érkezett volna. Futás közben is változtathatjuk a lap egyes jellemzôit, mint például a színeit vagy egyes ûrlap mezôk tartalmát.

Segítséget kaphatunk ahhoz is, hogy lapjainkat egyedi navigációs lehetôségekkel egészítsük ki. Nyomógombokat definiálhatunk, amelyek különbözô lapokat hívhatnak elô, a lapunkat részekre, keretekre (frame) oszthatjuk és az egyes keretek tartalmát függetlenül változtathatjuk. Különbözô kiegészítô tevékenységeket végezhetünk egy lapra be- illetve kilépéskor, hivatkozások (link) követésekor.

JavaScript programok korlátozott mértékben befolyásolhatják a böngészônk mûködését, megjelenését is. Figyelmeztetô (alert) és megerôsítést kérô (confirm) ablakokat jeleníthetünk meg, a fent emlegetett kereteken túl akár önálló böngészô ablakokat nyithatunk meg, sôt ezek fontosabb megjelenési paramétereit pl. mérete, vannak-e menüi, stb. szabadon megadhatjuk. Tájékoztatható szövegeket jeleníthetünk meg az állapotsorban.

JavaScript programok

Megpróbálom röviden összefoglalni a JavaScript nyelv sajátosságait. Terjedelmi okokból csak az érdekesebb vonásokra térek ki, feltételezem, hogy olvasóim valamennyire ismerik a C-t és olvasták a korábbi Jáva cikkeimet is.

JavaScript és HTML

A JavaScript programokat a HTML formátumú dokumentumokba kell beágyazni, erre vezették be a következô szintaxist.

Ahogy a többi HTML elem esetében, itt sem jelent különbséget, ha kis- illetve nagybetûket használunk, azaz a <script> ... </script> ugyanúgy megtenné, viszont a programon belül már a Jávához hasonlóan a kis- és nagybetûk eltérô jelentéssel bírnak. A language opciót - jelenleg - nem szükséges megadni ugyan, de én célszerûnek tartom, mert a következôkben elôbukkanhatnak más parancsnyelvek is.

A <script> olyan HTML tag, amelyet le kell zárni, ezért egy JavaScript-et értô böngészô el tudja különíteni a programot a lap többi részétôl. Azonban ha olyan böngészôt használunk, amely ezt még nem érti, az ugyan magát a <script> és </script> tagokat figyelmen kívül hagyja, viszont a program szövegébe belegabalyodhat. Ezért célszerû a fenti példa szerint a teljes programot HTML megjegyzésbe (<!-- ... -->) zárni.

JavaScript programrészlet a HTML dokumentumban bárhol akár többször is elôfordulhat. A programszöveg értelmezése, végrehajtása a <script> tag teljes betöltése után kezdôdik meg. A JavaScript programban függvények definiálása és végrehajtandó utasítások sorozata keveredhet. A függvénydefiníciók kiértékelése csak a definíció "megjegyzésével" jár, a függvényeket a HTML lap más pontjain, általában a késôbbiekben megismert eseménykezelôkben hívhatjuk meg. Célszerû a lapon felhasznált összes függvényt a lap fejében a <head> és </head> között definiálni.

Az egyszerû programrészleteket a böngészô azonnal végrehajtja, azaz például a

lap középre kerülô, nagybetûs "Éljen a JavaScript" szövegét a program állította elô, míg a "... és vesszenek a vetélytársai!" szöveg a HTML dokumentum statikus része. (Próbáld ki!)

Adatok, változók és kifejezések

A JavaScript programban elôforduló adatok csak a következô négy különbözô típusba tartozhatnak: objektum, számérték (amely egyaránt jelenthet egész vagy valós számokat), szöveg (karaktersorozat) és logikai érték (true és false).

A kifejezések szintaxisa nem tér el a C-szerû nyelvekben megszokottaktól, az egyes értékeket megjelenítô literálokon túl változók illetve függvényhívások is elôfordulhatnak bennük. Kifejezések írásához felhasználhatjuk a C-bôl megismert összes szokásos operátort, beleértve az olyan egzotikusakat is, mint az értékadó operátorok (pl. =+), vagy a feltételes kifejezést (feltétel ? érték1 : érték2) is. Az aritmetikai és összehasonlító operátorok jól tûrik a szövegeket is, szükség esetén szó nélkül konvertálnak szövegek és számértékek között ide-oda, de a parseInt és parseFloat függvényekkel explicit konverziót is elôírhatunk, az eval függvény pedig egy szöveget, mint JavaScript kifejezést értékel ki. Szövegekre itt is értelmezett a + operátor.

Természetesen változókat is használhatunk, a névadási konvenciók a C-bôl ismertek, itt azonban nem kell az egyes változók típusát deklarálni, ugyanazon nevû változó élettartama során tetszôleges típusú értéket hordozhat. Változókat a következô két módon hozhatunk létre.

var név [= érték]

vagy

név = érték

Az elsô szerkezet, ha a elhagyjuk az értékadást, akkor nem definiált értékû változót hoz létre. A változók lehetnek globálisak, az egész programban felhasználhatók illetve lokálisak, amelyek csak az adott függvényen belül használhatók, ott viszont elfedhetik az azonos nevû globális változót. Az elsô fajta deklaráció az elôfordulási helyétôl függôen lehet globális és lokális is, a második az elôfordulásától függetlenül mindig globális.

Utasítások

A JavaScript csak a következô alapszavakat használja az utasításokhoz:

break continue for
for...in function if...else
new return var
while with

ám az összes Jáva alapszót is fenntartott, programozók által nem használható szóként kezeli. Az utasítások egy C programozó számára nagy meglepetéseket nem jelentenek, legfeljebb hiányzik nekik a switch szerkezet. Újdonság a for..in, new illetve a with utasítások, ezekrôl majd az objektumoknál szólok.

Függvények definiálására a

function fnév ( paraméterek ) { ... return érték }

forma szolgál. Látjuk, hogy a függvény visszatérési értékének típusát nem kell definiálni, ez is dinamikus, attól függ, hogy a return milyen értéket ad vissza. A függvény törzsében az egyes paraméterekre szokásos módon a nevükkel hivatkozhatunk, de a paramétereket egy tömb elemeiként is elérhetjük, pl. az

az elsô paraméterre hivatkozik, míg az

a paraméterek számát adja meg, így lehetôséget kapunk változó számú paraméteres függvények írására.

A függvényhívásnál a paraméterátadás érték szerint történik, azaz a függvény ugyan módosíthatja a paraméterként megkapott értéket, de ennek a hívóra semmilyen hatása nem lehet. Aki imádja mellékhatásokkal (side effect) áttekinthetetlenné tenni a programjait, az használjon gyakorta globális változókat.

Objektumok

A JavaScript objektum-modellje sokak számára furcsának tûnhet, engem leginkább a LISP nyelv objektumorientált kiterjesztéseire emlékeztet. A JavaScript objektum <tulajdonság, érték> párok halmaza. Az egyes tulajdonságokhoz (property) az ismert

szintaxissal hivatkozhatunk, az értékét használhatjuk, módosíthatjuk. Egy objektum létrehozására a new utasítás szolgál, amely által lehívott függvény kitöltheti az objektum tulajdonságainak értékeit. Például:

utasítássorozat létrehoz egy objektumot, amely értéket rendel a first_name, last_name, age tulajdonságaihoz, majd életkorát megváltoztatja. A függvényen belül a this az aktuális, esetünkben az éppen létrehozott objektumra hivatkozik.

A JavaScript objektumokat asszociatív tömböknek is tekinthetjük, ahol a tulajdonság nevekhez értékek tartoznak, amelyek a nevek alapján hozzáférhetôk. Ezt az analógiát erôsíti az is, hogy a tulajdonságokhoz az indexelésnek megfelelô szintaxissal is hozzáférhetünk, pl. a fenti példában írhattuk volna azt is, hogy

Ezek után nem meglepô, hogy JavaScript-ben külön tömbök nincsenek. Tömbnek olyan objektumot nevezünk, amely tulajdonságai a 0-tól kezdôdô egész számok, ezen felül van egy length nevû tulajdonsága a tömb "hosszának" tárolására. Lássunk egy trükkösebb tömb-konstruktor függvényt és felhasználását, amely kihasználja a változó számú paraméteres függvényt:

Érdekes a példa, látható, hogy a tömb értékei nem feltétlenül azonos típusúak, sôt egy objektum tulajdonságának értéke lehet egy másik objektum is. Természetesen mutatók itt sincsenek, de a null "üres objektum" itt is létezik.

Az egyes objektumokhoz függvényeket is rendelhetünk, így a szokásos módszereket kapjuk. Hosszas magyarázkodás helyett bôvítsük a fenti person példát.

A person által létrehozott objektumoknak lesz egy introduce tulajdonsága, amihez egy függvény tartozik. A program vastagon szedve kiírja, hogy "Szia, Nagy Dezsô vagyok."

Az objektumok összes tulajdonságán a for...in ciklussal lehet végighaladni, a következô függvény például elôállít egy olyan HTML szöveget, amely a paraméterként megadott (obj) és megnevezett (obj_name) objektum összes tulajdonságát és a hozzá tartozó értéket felsorolja.

Beépített objektumok

Ezek a programozási lehetôségek nem sokat érnének, ha nem lennének a JavaScript-ben elôre definiált objektumok, hozzá tartozó tulajdonságaikkal és módszereikkel. Szerencsére számos ilyen objektum van itt fel sem tudom mindet sorolni , ezek jó része a HTML lap egyes elemeire hivatkozik. Megadom a HTML lapokhoz tartozó egy objektumok hierarchiáját. A hierarchiának nincs köze az öröklôdéshez, csupán azt jelenti, hogy a hierarchiában fentebb álló objektum valamely tulajdonsága a lenti objektumot tartalmazza (hivatkozik rá).

Ha egy beépített objektumnak több azonos típusú eleme van, akkor azokra vagy tömbszerûen lehet hivatkozni, vagy az elem dokumentumban megadott neve alapján (NAME= opció). Bár minden egyes objektumhoz sok hasznos tulajdonság, módszer tartozik, aminek részletes ismertetésére nincs mód, a példák talán ízelítôt adnak a lehetôségekbôl.

A fenti objektumokon túl van még 2 segéd objektum, a Date (dátum és idôkezelés), Math (matematikai függvények és konstansok).

A JavaScript szövegei string objektumok, amelyeken számos transzformációs, HTML-nek megfelelô formázó függvény van értelmezve. Például a

programrészlet a "Hello, world!" szöveget piros színben jeleníti meg.

Eseménykezelés

A HTML lapok különbözô elemeihez magához a laphoz, az egyes hivatkozásokhoz, ûrlap elemekhez a böngészô az egér mozgatásával, a billentyûzet használatával kapcsolatban különbözô eseményeket rendel. Az egyes események feldolgozására az új eseménykezelôk (event handler) szolgálnak, amelyeket a megfelelô HTML elem definíciójánál lehet megadni. Az eseménykezelô egy tetszôleges JavaScript utasítássorozatot tartalmazhat, leggyakrabban egy függvény meghívását tartalmazza.

A következô táblázat megadja a lehetséges eseménykezelôk nevét és a lehívását kiváltó esemény. Figyelem, különbözô HTML elemeknél különbözô események értelmesek.

onLoad betöltünk egy oldalt a böngészôbe
onUnload kilépünk egy betöltött oldalról
onFocus az ûrlap valamelyik eleme a fókuszba kerül, azaz a billentyûzetrôl érkezô karaktereket fogadja
onBlur a fókusz elmozdul az ûrlap valamelyik elemérôl
onSelect az ûrlap valamelyik bemeneti mezôjét kiválasztották
onChange az ûrlap valamelyik elemének (szöveg, választás) értékét megváltoztatták
onClick rákattintottak egy ûrlap elemre (pl. nyomógombra), vagy hivatkozásra
onSubmit elküldenek egy ûrlapot a szerver felé (a submit gombra kattintottak)
onMouseOver az egér egy hivatkozás, vagy dokumentum címke fölé kerül

A következô példa egyszerû kalkulátort valósít meg, ahol a két mezôbe számokat írhatunk, a közöttük lévô legördülô listában a 4 alapmûvelet közül választhatunk, majd az egyenlôségjellel ellátott nyomógombot megnyomva az eredmény mezôben megjelenik a számítás eredménye.

Eddig tartott a dokumentum feje. Figyeljük meg a compute függvény belsejében a paraméterként megkapott ûrlapobjektum egyes részeire a nevükkel hivatkozunk: A és B a két (bementi), result az (eredmény) szövegmezô, op pedig a mûveletet kiválasztó legördülô lista. A listán belül a kiválasztott elem sorszámát a selectedIndex módszer adja vissza, ennek segítségével indexelve megkaphatjuk a mûveleti jelet, mint szöveget. Az eval pedig szöveget vár és megpróbálja kifejezésként kiértékelni.

Az egyenlôségjel feliratú (VALUE=" = ") nyomógombhoz rendeltünk egy eseménykezelôt, amely akkor aktiválódik, ha rákattintottunk (onClick), ekkor meghívja a compute függvényt, átadva neki az aktuális ûrlapot. (Próbáld ki!)

Érdekes trükkök

Ízelítôül szeretnék néhány olyan JavaScript példát mutatni, amely ötleteket adhat HTML lapjaink feldíszítéséhez.

Kattintásra induló JavaScript függvény

A JavaScript megjelenésével kibôvült a böngészôknek megadható címek (URL, Universal Resource Locator) szintaxisa is. Ismeretes, hogy az URL elsô, a kettôspontig terjedô része a szerverrel kapcsolattartás protokollját definiálta, pl. http:, ftp:, gopher:. Ez a választék most bôvült a javascript: (vagy az azonos jelentésû, de régies mocha:) taggal. Ezután az URL többi része helyett egy JavaScript utasítást írhatunk, amelyet a hivatkozás aktiválásánál a böngészô végrehajt. Például a következô példa azt illusztrálja, hogyan csinálhatunk olyan hivatkozást, amelyre kattintva elôbb egy megerôsítô kérdést kapunk és csak azt jóváhagyva tölti be a böngészô az új oldalt.

Látható, hogy a HREF tag egy függvényhívást tartalmaz, amely paraméterként megkaphat egy tetszôleges URL-t (csak arra vigyázzunk, hogy azt aposztrófok és ne idézôjelek közé zárjuk. A confirmFollow függvény akkor tölt csak be új lapot, ha a felbukkanó megerôsítô kérdésre az OK gomb lenyomásával válaszolunk. Megjegyzendô, hogy a megerôsítô ablak nyomógombjainak felirata sajnos - jelenleg? - angol marad, nem változtatható. Ugyancsak változtathatatlan az általunk kiírt szöveg felett az ablakban megjelenô "JavaScript confirm:" szöveg is.

Állapotsor kezelés

Gyakran használható fortély, hogy a böngészô állapotsorában különbözô kiegészítô üzenetek jelennek meg. Elsô példaként megmutatom, hogyan lehet az állapotsorba valami magyarázó szöveget kiírni akkor, ha az egér egy hivatkozás fölött áll (normálisan a Netscape az URL-t mutatja meg.) Legegyszerûbben a következô módon járhatunk el:

A fenti HREF tag a "kapcsolat" szó fölé állva az egérrel meghívódik az onMouseOver eseménykezelô, amely egyszerûen az állapotsorba írja a "magyarázó szöveg"-et, majd igaz logikai értékkel visszatér.

A megoldás szépséghibája, hogy ha elmozdulunk az egérrel, az állapotsorban ott marad a kiírt szöveg mindaddig, amíg mást nem írunk mi vagy a böngészô oda. Sajnos olyan eseménykezelô nincs, amely akkor indulna be, ha elmozdulunk az egérrel, de az alábbi két egyszerû függvénnyel adott idôzítés után letörölhetjük az állapotsort.

A stat függvény elôször felülírja az állapotsort, majd a setTimeout hívással egy JavaScript programrészlet itt az erase függvény meghívását idôzíti 1500 msec-kel késôbbre. A fenti függvények segítségével a HREF tagba már elegendô a stat függvényt lehívni:

Néhol az állapotsort "fényreklámként" használják, az állapotsorban valamilyen szöveget görgetnek jobbról balra. Bár van, akit ez idegesít, de azért magyarázatok nélkül mutatok egy egyszerû programot. A lényeges trükk az idôzített végrehajtáson túl az, hogy a fényreklám a lap betöltésekor az onLoad esemény hatására indul el.(Próbáld ki!)

Új ablak nyitása

A JavaScript lehetôvé teszi, hogy új böngészô ablakot nyissunk, sôt ahogy az a következô példában szereplô open paramétereibôl már gyanítható, az ablak megjelenését is kézben tarthatjuk. Itt pl. egy olyan ablakot nyitunk meg, amelynek megadjuk pixel-ekben a kezdeti méretét és megtiltjuk, hogy a felhasználó ezt megváltoztassa. Az új ablaknak nem lesz sem eszközsora, sem menüi.

A példa egy olyan lapot jelenít meg, ahol egetlen nyomógomb van, erre rákattintva megnyílik az új ablak is. Az új ablak "Vége" feliratú gombjával le is zárhatjuk azt. (Próbáld ki!)

Mi lesz veled JavaScript?

Vajon mit hoz a jövô, mennyire perspektivikus ez a programozási technológia? A HTML dokumentumokkal való szoros összefonódása népszerûvé teszi, apróságokat tényleg könnyen meg lehet a segítségével valósítani. Én mégsem látom a jövôjét olyan biztosnak, mint nagyobb testére, a Jáva jövôjét.

A JavaScript kevésbé dokumentált, mint a Jáva. Ugyan jelentek meg már könyvek errôl is, de azért még vadászni kell a megbízható információk után. Nem könnyíti meg a programozók életét a Netscape sem, az újabb böngészô verziókkal a nyelv is változik. Sajnos a biztonsági kérdések sincsenek annyira átgondolva, mint a Jáva nyelvnél.

Másik problémának a nyelv támogatottságát érzem. Mivel ez szorosan a böngészô programokhoz tartozik, önálló JavaScript alkalmazások nem létezhetnek, ezért csak a böngészôket író szoftverházakon múlik, vajon ráharapnak-e. Jelenleg a Netscape böngészôje az egyetlen, amelyik ismeri. A hírek szerint a Microsoft Internet Explorer 3.0-s változata is támogatni fogja, valószínûleg a HotJava-ba is belekerül. Viszont kimaradt a közelmúltban nagy harcok után és kompromisszumokat kötve elfogadott HTML 3.2-es specifikációból.

No meg mások is rájöttek arra, hogy szükség van ilyen egyszerû, böngészô oldali programozási lehetôségre. Microsoft-éknál az egyszerûséget mindig is a Visual Basic jelentette, ôk most nagyon erôltetnek egy erre épülô, VBscript technológiát. Az Oracle kijött az új böngészôjével, amely saját, ugyancsak a Basic-hez hasonló parancsnyelvet ismer. Na és ha halkan is, de idônként hallani a SUN-nál dolgozó fejlesztôi csoport véleményét, akik HTML parancsnyelvként a UNIX világban szabadon hozzáférhetô volta miatt nagyon elterjedt Tcl/Tk technológiát támogatják.

Arra már a fenti szoftvergyártók is rájöttek, hogy valami hasonló eszköz jó lenne a szerver oldali programok írásához, a jelenlegi CGI mechanizmus esetleges, nem hatékony. Mindenki arrafelé kacsintgat, hogy hasonló egyszerû nyelvi eszközzel támogassák ezt a feladatot is. Sôt a Jáva is elmozdult ebbe az irányba, a programkák (applet) mellett már beszélnek "szerverkékrôl" (servlet) is, állítólag már írják a hozzá tartozó API-t.


Kiss István

updated: 96/06/30, http://www.eunet.hu/infopen/cikkek/java/javascr.html