Mikor sok-sok évvel ezelőtt leírtuk életünk első JavaScript kódját — amely legtöbb esetben csupán annyiból állt, hogy az egeret egy kép fölé mozgatva leváltotta azt — vajon hányan gondoltuk, hogy ez a nyelv ilyen óriási sikereket fog elérni. Kétkedve ráztuk volna a fejünket, ha valaki azzal áll elő, hogy egyszer szoftvereket, sőt asztali alkalmazásokat, fejlesztői eszközöket, operációs rendszereket fogunk fejleszteni vele. Mikor 1996-ban Brendan Eich és a csapata a Netscape műhelyében — mindössze pár hét alatt — specifikálta a nyelvet még senki se számított rá, hogy az ilyen formában, ennyire sokáig megmarad. Ahogy azonban terjedt és fejlődött az internetes kultúra, ahogy emberek millió csatlakoztak a web-böngészők alkotta új platformhoz, a JavaScript szinte magától tört utat magának. A számítógépek és hálózatok gyorsulásával egyre nőtt a fogyasztói igény, a felhasználók látványos, könnyen kezelhető weboldalakat szerettek volna látni, és ahogy a multimédia mind több formája vált természetessé számunkra a weben, úgy váltak életünk részévé a webalkalmazások.
Ma már a legtöbben nem csak kommunikációra, filmezésre, zenehallgatásra vagy épp levelezésre használunk JavaScript alapú szoftvereket, de egyre többen munkára is. Az internetes böngésző egy olyan platformmá vált, ami lassan minden elektronikus eszközön ott van, emberek milliárdjait kötve össze. Mindegy, hogy Windows-ról vagy OSX-ről, mobil eszközről vagy okostévéről kapcsolódunk, mindenhonnan ugyanazt a tartalmat láthatjuk. A kollaboratív élmény olyan könnyen elérhetővé vált, olyan új lehetőségek előtt nyitotta meg az utat, amiről a felhasználók és a fejlesztők korábban csak álmodhattak. Természetesnek vesszük, hogy egy webalkalmazást — közvetlenül vagy közvetve, de — megoszthassunk, együtt használjunk családtagjainkkal, ismerőseinkkel, munkatársainkkal.
A kliens oldali webfejlesztés ma már megkerülhetetlen — és egyre inkább úgy, hogy tűnik eggyé vált a JavaScript nyelvvel.
Feltételezzük, hogy e könyv olvasói már valamelyest találkoztak a JavaScripttel, így néhány alapvető dologra már nem térnénk ki részletesen. Nem kívánunk a futtatókörnyezetről beszélni, a fejlesztőeszközökről vagy éppen a nyelv történelméről. Mielőtt azonban mélyebben belevágnánk a JavaScript rejtelmeibe, nézzünk meg egy-két dolgot, amire a továbbiakban építkezni fogunk.
Bár ma még sokkal jelentősebb a JavaScript kliens oldali felhasználása, óriási ütemben nő népszerűsége a szerver-oldalon is. Ez elsősorban a Node.js-nek köszönhető, amely egy — a Chrome böngésző alatt is futó — V8 nevű, gyors és modern JavaScript motor fölé írt futtatókörnyezet.
Nem csoda, hogy ilyen sikeressé vált, hiszen a Node.js telepítése és használata is pofonegyszerű — olyannyira, hogy ma már a webfejlesztők elsődleges eszközkészletévé lépett elő. A Node alá írt előfordítók, csomagkezelők, task menedzserek minden korábbinál nagyobb produktivitással kecsegtetnek. Ma már nem meglepő, hogy egy új osztálykönyvtárat nem kézzel letöltve és a kódba betallózva, hanem Bower segítségével telepítünk; egy új modellt vagy tesztet nem manuálisan, hanem Yo-val generáltatunk; vagy, hogy egy paranccsal buildeljük és deployoljuk a munkánkat a Grunt vagy a Gulp segítségével. Ezek az eszközök — és hozzájuk hasonlóan több ezer másik — mind Node.js alatt futnak, már nem is explicit szerverként, hanem asztali alkalmazásként. Ma még álmodozásnak tűnik, azonban lehet, hogy a jövőben — a node-webkit jellegű projekteknek köszönhetően — már nem csak konzolos segédprogramokat, hanem teljes értékű, multiplatformos, grafikus asztali alkalmazásokat fogunk JavaScriptben fejleszteni.
A Node.js alatti kódolás szinte semmiben nem különbözik a kliens oldali, hagyományos JavaScripttől — csupán olyan plusz API-kat biztosít, amellyel feloldja a böngészők korlátozásait. A szerver-oldalon így hozzá tudunk férni a fájlrendszerhez, az adatbázisokhoz, sőt akár az operációs rendszer alacsony-szintű műveleteihez is.
Ne feledjük azonban, hogy a szerver-oldali működés is hasonló a böngészőbelihez: csupán egyetlen szálon fut. A kliens oldalon ez nem is okoz túlzottan nagy problémát, hiszen egyetlen felhasználó van, azonban a szerver oldalra ez már nem igaz. Ahhoz, hogy rengeteg felhasználót, nagy hatékonysággal tudjunk kiszolgálni, a műveleteket amennyire csak lehet aszinkronná kell tenni, esélyt adva más folyamatok és felhasználók számára. Erről bővebben az aszinkron programozással foglalkozó fejezetben írunk.
Amíg a 4-5 évvel ezelőttig a szoftverek közötti adatkommunikáció elsődleges formája az XML volt, addig ma ez a trend éles kanyart véve fordult a JSON felé. A JavaScript Object Notation szabvány a nyelv úttörőjéhez Douglas Crockford-hoz fűződik, aki egy, a JavaScript számára módosítás nélkül megemészthető adatformát definiált. A JSON legfontosabb előnye az XML-el szemben az egyszerűségében rejlik — egyszerű JavaScript literálokkal fejezhető ki az összes adattípus, az ember szem számára is olvasható és az XML-nél sokkal kevésbé verbózus formában.
{ "superman": { "features": { "canFly": true, "useGlasses": true } }, "spiderman": { "features": { "canFly": false, "useGlasses": true } } }
A programozási nyelvek nagy részéhez hasonlóan a JavaScriptben is eltárolhatóak állapotok, az értékeket a var kulcsszó segítségével egyszerű változókba menthetjük.
var variable = 'Some variable';
A console.log segítségével bármikor a futtatókörnyezet konzoljára írhatunk egy értéket:
console.log(variable); // => 'Some variable'
A könyv rengeteg példájában az assertEquals nevű metódust fogjuk használni, amely két érték összehasonlítására szolgál. A működése nagyon egyszerű: ha a paraméterül átadott értékek azonosak, akkor igazat, egyébként hamisat fog visszaadni a függvény.
assertEquals(1, 1); // => true assertEquals(1, 2); // => false
Az assertEquals implementációja sem okozhat gondot senkinek, hiszen egyetlen identitásvizsgálatból áll. Első paramétere az elvárt érték, míg a második a vizsgált kifejezés értéke lesz.
var assertEquals = function(expectedValue, actualValue) { return expectedValue === actualValue; };
Egyszerű értékekre a fentiek nagyszerűen működnek, azonban az objektumokra és a többdimenziós adatokra sajnos nem igazán. Ennek oka az, hogy az objektumok referenciaként adódnak át, az identitásvizsgálatnál pedig nem a tartalmukat vizsgálja a környezet, hanem azt, hogy ugyanarról az objektumról van-e szó. Szerencsére nem feltétlenül kell ezeket az eseteket bonyolult vizsgálatokkal, mélységi bejárással lekezelni: ha a JSON.stringify metódussal JSON formátumúvá konvertáljuk az értékeket, akkor a kapott sztring már tökéletesen összehasonlítható:
var assertEquals = function(expectedValue, actualValue) { return JSON.stringify(expectedValue) === JSON.stringify(actualValue); }; assertEquals({ a: 1 }, { a: 1}); // => true assertEquals({ a: 1 }, { a: 2}); // => false
A következőkben, a példákban szereplő assertEquals — hacsak nem írjuk ki explicit az összehasonlítás eredményét — mindig igaz állításként fog szerepelni.
A JavaScript elnevezést historikus okokból, ma elsősorban gyűjtőfogalomként használjuk — azonban a nyelv EcmaScript (ES) néven lett szabványosítva. A könyv írása idején az ES5 a legtöbb böngésző által támogatott szabvány, de az ES6 specifikálása is lassan véglegesedik, így várható támogatottságának hirtelen megugrása.
Ma még sok problémát okoz a régebbi kliensek támogatása, és sajnos nem valószínű, hogy a közeljövőben óriási változások történnének ezen a téren. Ha széles körben elterjednek az always green böngészők — vagyis azok, amelyek minden új szoftververzió kiadása esetén automatikusan lefrissítik önmagukat — akkor végre esély nyílik arra, hogy a nyelv fejlesztései rugalmasabban, kisebb átfutási idővel jussanak el a többség által használható állapotba.
Szerencsére nem olyan rossz a helyzet: a relatíve kevés szintaktikai változástól eltekintve, minden módosítás emulálható a régebbi, legacy klienseken is. Ehhez nincs másra szükség, mint, hogy az egyes ES5 vagy ES6-os kiegészítések úgynevezett polyfill-eit töltsünk be a projektünkbe. Az es5-shim segítségével például az 5-ös szabvány által definiált új funkciók szinte teljes készletét elérhetővé tehetjük a régi böngészőkön csupán azzal, hogy egy JavaScript fájlt betöltünk a HTML kód legelején. A modernizr GitHub oldalán egy folyamatosan bővülő listából választhatjuk ki a nekünk megfelelő polyfill-t.
A továbbiakban, a könyvben szereplő kódok ES5 kompatibilis futtatókörnyezetet feltételeznek, azonban kitekintésként néhány ES6-os funkciót is meg fogunk említeni. Utóbbi esetben mindig fel fogjuk hívni a figyelmet arra, hogy ES6 kompatibilis környezetet kell teremtenünk a kód futtatása előtt.
Ebben a tananyagban elsősorban a modern kliensoldali programozási mintákkal ismerkedünk. Részletesen áttekintjük a JavaScript nyelv elemeit, elsősorban abból a célból, hogy kellő alapot nyújthassunk a magasabb szintű programozási koncepcióknak és nyelvi megoldásoknak. Ezt követően ezekben a koncepciókban mélyedünk el először csak a nyelvben található programozási mintákra koncentrálva, majd kilépve a nyelv keretei közül megnézzük, hogy a böngészőben lévő elemek hogyan programozhatók általa. Szót ejtünk a magasabb szintű programozási egységekről, kódszervezési kérdésekről, így részletesen tárgyaljuk a modulokat, a programozási mintákat, a magas szintű tervezési mintákat, valamint a kliensoldali programozásra oly jellemző aszinkron programozás által felvetett problémák megoldási módjait.
A tananyag végén kitekintést teszünk a népszerű szerveroldali környezet, a PHP nyelv modern programozási mintáira is.
A tananyag az ELTE - PPKE informatika tananyagfejlesztési projekt (TÁMOP-4.1.2.A/1-11/1-2011-0052) keretében valósult meg.
A tananyag elkészítéséhez az ELTESCORM keretrendszert használtuk.