034.2 Lecke 1
Tanúsítvány: |
Web Development Essentials |
---|---|
Verzió: |
1.0 |
Témakör: |
034 JavaScript programozás |
Fejezet: |
034.2 JavaScript adatstruktúrák |
Lecke: |
1/1 |
Bevezetés
A programozási nyelvek, akárcsak a természetes nyelvek, a valóságot szimbólumok segítségével ábrázolják, amelyeket értelmes kijelentésekké kombinálnak. A programozási nyelv által reprezentált valóság a gép erőforrásai, például a processzorműveletek, az eszközök és a memória.
A számtalan programozási nyelv mindegyike elfogad egy paradigmát az információ ábrázolására. A JavaScript a magas szintű nyelvekre jellemző konvenciókat alkalmazza, ahol a legtöbb részlet, például a memória kiosztása implicit, ezzel lehetővé téve a programozó számára, hogy a szkript céljára koncentráljon az alkalmazás kontextusában.
Magas szintű programozási nyelvek
A magas szintű nyelvek absztrakt szabályokat biztosítanak, így a programozónak kevesebb kódot kell írnia egy ötlet kifejezésére. A JavaScript kényelmes módokat kínál a számítógép memóriájának kihasználására, olyan programozási koncepciókat használ, amelyek leegyszerűsítik az ismétlődő gyakorlatok írását, és amelyek általában elegendőek a webfejlesztő céljainak az eléréséhez.
Note
|
Bár lehet speciális mechanizmusokat használni az aprólékos memóriaeléréshez, az egyszerűbb adattípusok, amelyeket megvizsgálunk, általánosabb használatúak. |
A webes alkalmazások tipikus műveletei abból állnak, hogy adatokat kérnek le valamilyen JavaScript utasításon keresztül, majd tárolják őket, hogy aztán feldolgozzák és végül megjelenítsék a felhasználónak. Ez a tárolás meglehetősen rugalmas a JavaScriptben, minden célra megfelelő tárolási formátumok állnak rendelkezésre.
Konstansok és változók deklarálása
Az adatok tárolására szolgáló konstansok és változók deklarálása minden programozási nyelv sarkalatos pontja. A JavaScript átveszi a legtöbb programozási nyelv konvencióját, és a név = érték
szintaxissal rendel értékeket a konstansokhoz vagy változókhoz. A bal oldali konstans vagy változó a jobb oldali értéket veszi fel. A konstans vagy változó nevének betűvel vagy aláhúzással kell kezdődnie.
A változóban tárolt adatok típusát nem kell megadni, mivel a JavaScript egy dinamikusan tipizált nyelv. A változó típusára a hozzá rendelt értékből következtet. A deklarációban azonban célszerű bizonyos attribútumokat kijelölni, hogy a várt eredményt garantálni lehessen.
Note
|
A TypeScript egy JavaScript által inspirált nyelv, amely az alacsonyabb szintű nyelvekhez hasonlóan lehetővé teszi változók deklarálását bizonyos adattípusokhoz. |
Konstansok
A konstans egy olyan szimbólum, amely a program indításakor egyszer kerül hozzárendelésre, és soha nem változik. A konstansok hasznosak fix értékek megadására, mint például a PI
konstans meghatározása 3.14159265 értékre, vagy a COMPANY_NAME
a vállalat nevének tárolására.
Vegyünk például egy webes alkalmazásban egy klienst, amely időjárási információkat kap egy távoli szerverről. A programozó dönthet úgy, hogy a szerver címének állandónak kell lennie, mert az nem fog változni az alkalmazás futása során. A hőmérsékleti információ azonban a szerverről érkező minden egyes új adat beérkezésekor változhat.
A szerverhez intézett lekérdezések közötti időintervallum is meghatározható konstansként, amely a program bármely részéből lekérdezhető:
const update_interval = 10;
function setup_app(){
console.log("Frissítés minden " + update_interval + "percben");
}
A setup_app()
függvény meghívásakor az Frissítés minden 10 percben
üzenet jelenik meg a konzolon. Az update_interval
név elé helyezett const
kifejezés biztosítja, hogy az értéke a szkript teljes végrehajtása során ugyanaz maradjon. Ha egy konstans értékének visszaállítására teszünk kísérletet, akkor TypeError: Assignment to constant variable
hiba jelenik meg.
Változók
A const
kifejezés nélkül a JavaScript automatikusan feltételezi, hogy az update_interval
egy változó, és hogy az értéke módosítható. Ez egyenértékű a változó explicit deklarálásával, amit a var
kifejezéssel tehetünk meg:
var update_interval;
update_interval = 10;
function setup_app(){
console.log("Frissítés minden " + update_interval + "percben");
}
Vegyük észre, hogy bár az update_interval
változót a függvényen kívül definiáltuk, a függvényen belülről érjük el. A függvényeken vagy szögletes zárójelekkel ({}
) közbezárt kódblokkokon kívül deklarált bármely konstans vagy változó globális hatókörű, azaz a kód bármely részéből elérhető. Ennek az ellenkezője nem igaz: egy függvényen belül deklarált konstans vagy változó lokális hatókörrel rendelkezik, tehát csak magában a függvényben érhető el. A zárójeles kódblokkok, például az if
döntési struktúrákban vagy a for
ciklusokban elhelyezett blokkok a konstansok hatókörét behatárolják, de a var
-ként deklarált változókét nem. A következő kód például érvényes:
var success = true;
if ( success == true )
{
var message = "Sikeres tranzakció";
var retry = 0;
}
else
{
var message = "Sikertelen tranzakció";
var retry = 1;
}
console.log(message);
A console.log(message)
utasítás képes hozzáférni a message
változóhoz, annak ellenére, hogy az az if
struktúra kódblokkjában lett deklarálva. Ugyanez nem történne meg, ha a message
konstans lenne, ahogyan azt a következő példa mutatja:
var success = true;
if ( success == true )
{
const message = "Sikeres tranzakció";
var retry = 0;
}
else
{
const message = "Sikertelen tranzakció";
var retry = 1;
}
console.log(message);
Ebben az esetben egy ReferenceError: message is not defined
típusú hibaüzenet jelenik meg, és a szkript leáll. Bár korlátozásnak tűnhet, a változók és konstansok hatókörének behatárolása segít elkerülni a szkript törzsében és a különböző kódblokkokban feldolgozott információk közötti zavart. Ezért a var
helyett let
-tel deklarált változók hatókörét is korlátozzák a szögletes zárójelekkel határolt blokkok. Vannak más finom különbségek is a változók var
-ral vagy let
-tel történő deklarálása között, de a legjelentősebb a változó hatókörét érinti.
Értékek típusai
Legtöbbször a programozónak nem kell aggódnia a változóban tárolt adatok típusa miatt, mert a JavaScript automatikusan azonosítja azt az egyik primitív típussal a változóhoz való első érték hozzárendelése során. Egyes műveletek azonban specifikusak lehetnek az egyik vagy másik adattípus esetén, és mérlegelés nélkül használva hibát eredményezhetnek. A JavaScript strukturált típusokat is kínál, amelyek lehetővé teszik, hogy egynél több primitív típust kombináljunk egyetlen objektumba.
Primitív típusok
A primitív típuspéldányok gyakorlatilag azok a hagyományos változók, amelyek csak egy értéket tárolnak. A típusok implicit módon vannak definiálva, így a typeof
operátorral azonosítható, hogy milyen típusú értéket tárol egy változó:
console.log("A nemdefiniált változók dípusa", typeof variable);
{
let variable = true;
console.log("A `true` érték típusa " + typeof variable);
}
{
let variable = 3.14159265;
console.log("Az `3.14159265` érték típusa " + typeof variable);
}
{
let variable = "Text content";
console.log("A `Text content` érték típusa " + typeof variable);
}
{
let variable = Symbol();
console.log("A symbol típusa " + typeof variable);
}
Ez a szkript kiírja a konzolra, hogy az egyes esetekben milyen típusú változót használtunk:
A nemdefiniált változók típusa undefined A `true` érték típusa boolean A `3.114159265` érték típusa number A `Text content` érték típusa string A symbol típusa symbol
Vegyük észre, hogy az első sor egy be nem jelentett változó típusát próbálja megkeresni. Ez azt eredményezi, hogy az adott változót undefined
-ként azonosítja. A symbol
típus a legkevésbé intuitív primitív. Célja, hogy egy objektumon belül egyedi attribútumnevet adjon, amikor nincs szükség konkrét attribútumnév definiálására. Az objektum az egyik adatszerkezet, amelyet a következőkben megvizsgálunk.
Strukturált típusok
Bár a primitív típusok elegendőek egyszerű rutinok írásához, a komplexebb alkalmazásokban való kizárólagos használatuknak vannak hátrányai. Egy e-kereskedelmi alkalmazást például sokkal nehezebb lenne megírni, mivel a programozónak módot kellene találnia arra, hogy a tételek listáit és a hozzájuk tartozó értékeket csak primitív típusú változók segítségével tárolja.
A strukturált típusok leegyszerűsítik az azonos jellegű információk egyetlen változóba való csoportosítását. A bevásárlókosárban lévő tételek listája például egyetlen array (tömb) típusú változóban tárolható:
let cart = ['Tej', 'Kenyér', 'Tojás'];
Ahogy a példában is látható, egy tömböt szögletes zárójelekkel jelölünk. A példa a tömböt három sztring literállal töltötte fel, ezért használunk idézőjeleket. Változókat is lehetnek tömb elemei, de ebben az esetben idézőjelek nélkül kell őket jelölni. A tömb elemeinek számát a length
tulajdonsággal lehet lekérdezni:
let cart = ['Milk', 'Bread', 'Eggs'];
console.log(cart.length);
A konzol kimenetén a 3
jelenik meg. Új elemeket a tömbhöz a push()
metódussal adhatunk hozzá:
cart.push('Candy');
console.log(cart.length);
Ezúttal a megjelenített mennyiség 4
lesz. A lista minden eleme elérhető a numerikus indexével, 0
-val kezdve:
console.log(cart[0]);
console.log(cart[3]);
A konzolon látható kimenet az alábbi lesz:
Tej Cukorka
Ahogy a push()
metódust használhatjuk elem hozzáadására, a pop()
segítségével eltávolíthatjuk a tömb utolsó elemét.
A tömbben tárolt értékeknek nem kell azonos típusúaknak lenniük. Lehetőségünk van például arra, hogy az egyes tételek mellett tároljuk a mennyiséget. Az előző példához hasonló bevásárlólistát a következőképpen lehetne felépíteni:
let cart = ['Tej', 1, 'Kenyér', 4, 'Tojás', 12, 'Cukorka', 2];
// A tétel indexei párosak
let item = 2;
// A mennyiségek indexei páratlanok
let quantity = 3;
console.log("Tétel: " + cart[item]);
console.log("Mennyiség: " + cart[quantity]);
A kód futtatása után az alábbi kimenet jelenik meg a konzolon:
Tétel: Kenyér Mennyiség: 4
Talán már látjuk, hogy a tételek nevének és a hozzájuk tartozó mennyiségeknek egyetlen tömbben való kombinálása nem feltétlenül jó ötlet, mivel a köztük lévő kapcsolat nem egyértelmű az adatszerkezetben, és nagyon érzékeny az (emberi) hibákra. Ha egy tömböt használnánk is a tételek neveihez és egy másik tömböt a mennyiségekhez, a lista integritásának fenntartása ugyanolyan gondosságot igényelne, és nem is lenne túl produktív. Ezekben a helyzetekben a legjobb alternatíva egy megfelelőbb adatszerkezet: egy objektum használata.
A JavaScriptben egy objektum típusú adatszerkezet lehetővé teszi, hogy tulajdonságokat kössünk egy változóhoz. Továbbá, szemben a tömbökkel, az objektumot alkotó elemeknek nincs rögzített sorrendje. Egy bevásárlólista elem például lehet egy objektum a name
(név) és quantity
(mennyiség) tulajdonságokkal:
let item = { name: 'Tej', quantity: 1 };
console.log("Tétel: " + item.name);
console.log("Mennyiség: " + item.quantity);
Ez a példa bemutatja, hogy egy objektumot kapcsos zárójelek ({}
) használatával lehet definiálni, ahol minden tulajdonság/érték pár kettősponttal, a tulajdonságok pedig vesszőkkel vannak elválasztva. A tulajdonság a változó.tulajdonság formátummal érhető el, mint az item.name
esetén, mind az olvasáshoz, mind az új értékek hozzárendeléséhez. A kód futtatása után az alábbi kimenet lesz látható a konzolon:
Tétel: Tej Mennyiség: 1
Végül, minden egyes tárgyat reprezentáló objektum bekerülhet a bevásárlólista tömbjébe. Ezt közvetlenül a lista létrehozásakor lehet megtenni:
let cart = [{ name: 'Tej', quantity: 1 }, { name: 'Kenyér', quantity: 4 }];
A korábbiakhoz hasonlóan egy elemet reprezentáló új objektumot később is hozzáadhatunk a tömbhöz:
cart.push({ name: 'Tojás', quantity: 12 });
A lista elemeit mostantól az indexük és a tulajdonságuk neve alapján lehet elérni:
console.log("Harmadik tétel: " + cart[2].name);
console.log(cart[2].name + " mennyisége: " + cart[2].quantity);
A kód futtatása után az alábbi kimenet jelenik meg a konzolon:
Harmadik tétel: Tojás Tojás mennyisége: 12
Az adatszerkezetek lehetővé teszik a programozó számára, hogy kódja sokkal rendezettebb és könnyebben karbantartható legyen, akár az eredeti szerző, akár a csapat többi programozója által. Emellett a JavaScript függvények sok kimenete strukturált típusokban van, amelyeket a programozónak megfelelően kell kezelnie.
Operátorok
Eddig nagyjából csak azt láttuk, hogyan rendelhetünk értékeket az újonnan létrehozott változókhoz. Bár egyszerű, de bármelyik program számos más manipulációt végez a változók értékeivel. A JavaScript többféle operátor típust kínál, amelyek közvetlenül egy változó értékére hatnak, vagy a művelet eredményét egy új változóban tárolják.
A legtöbb operátor az aritmetikai műveletekre irányul. Ha például növelni szeretnénk egy tétel mennyiségét a bevásárlólistán, használjuk egyszerűen a +
összeadó operátort:
item.quantity = item.quantity + 1;
A következő részlet kiírja a item.quantity
értékét a hozzáadás előtt és után. Ne keverjük össze a pluszjel szerepét a kódrészletben! A console.log
utasítások a pluszjelet két karakterlánc összekapcsolására használják.
let item = { name: 'Tej', quantity: 1 };
console.log("Tétel: " + item.name);
console.log("Mennyiség: " + item.quantity);
item.quantity = item.quantity + 1;
console.log("Új mennyiség: " + item.quantity);
A kód futtatása után az alábbi kimenet jelenik meg a konzolon:
Tétel: Tej Mennyiség: 1 Új mennyiség: 2
Vegyük észre, hogy a korábban az item.quantity
-ben tárolt értéket használjuk az összeadási művelet operandusaként: item.quantity = item.quantity + 1
. Csak a művelet befejezése után frissül az item.quantity
értéke a művelet eredményével. Ez a fajta aritmetikai művelet a célváltozó aktuális értékével elég gyakori, ezért léteznek olyan rövidített operátorok, amelyek lehetővé teszik ugyanennek a műveletnek a tömörített formában történő leírását:
item.quantity += 1;
A többi alapműveletnek is vannak rövidített, de egyenértékű operátorai:
-
a = a - b
egyenértékű az alábbival:a -= b
. -
a = a * b
egyenértékű az alábbival:a *= b
. -
a = a / b
egyenértékű az alábbival:a /= b
.
Az összeadáshoz és kivonáshoz egy harmadik formátum is rendelkezésre áll, amikor a második operandus csak egy egység:
-
a = a + 1
egyenértékű az alábbival:a++
. -
a = a - 1
egyenértékű az alábbival:a--
.
Egynél több operátor kombinálható ugyanabban a műveletben, és az eredményt egy új változóban lehet tárolni. A következő utasítás például kiszámítja egy tétel teljes árát és a szállítási költséget:
let total = item.quantity * 9.99 + 3.15;
A műveletek elvégzésének sorrendje a hagyományos sorrendet követi: először a szorzási és osztási műveletek, majd ezután következnek az összeadási és kivonási műveletek. Az azonos precedenciájú operátorok a kifejezésben való megjelenésük sorrendjében, balról jobbra haladva kerülnek végrehajtásra. Az alapértelmezett precedenciasorrend felülbírálásához használhatunk zárójeleket, mint például az a * (b + c)
kifejezésben.
Bizonyos helyzetekben a művelet eredményét nem is kell egy változóban tárolni. Ez az eset akkor áll fenn, amikor egy if
utasításon belül szeretnénk kiértékelni egy kifejezés értékét:
if ( item.quantiy % 2 == 0 )
{
console.log("A tételek mennyisége páros");
}
else
{
console.log("A tételek mennyisége páratlan");
}
A %
(modulo) operátor az első operandus és a második operandus osztásának maradékát adja vissza. A példában az if
utasítás azt ellenőrzi, hogy a item.quantity
és a 2
osztásának maradéka egyenlő-e nullával, azaz, hogy a item.quantity
2 többszöröse-e.
Ha a +
operátor egyik operandusa egy sztring, akkor a többi operátor kényszerítve lesz arra, hogy sztringgé alakuljon, és az eredmény összefűzött sztring lesz. Az előző példákban ezt a típusú műveletet használtuk a console.log
utasítás argumentumában szereplő sztringek és változók összefűzésére.
Nem biztos, hogy valóban ezt az automatikus átalakítást szeretnénk elérni. A felhasználó által egy űrlapmezőben megadott érték lehet, hogy sztringként kerül azonosításra, de valójában numerikus értékről van szó. Ilyen esetekben a változót először számmá kell alakítani a Number()
függvénnyel:
sum = Number(value1) + value2;
Ezenkívül fontos, hogy a művelet folytatása előtt ellenőrizük, hogy a felhasználó érvényes értéket adott-e meg. A JavaScriptben a hozzárendelt érték nélküli változó null
vesz fel. Ez lehetővé teszi a programozó számára, hogy a if ( value1 == null )
típusú döntési utasítással ellenőrizze, hogy egy változóhoz rendeltek-e értéket, függetlenül a változóhoz rendelt érték típusától.
Gyakorló feladatok
-
A tömb egy olyan adatszerkezet, amely több programozási nyelvben is jelen van, némelyik azonban csak azonos típusú elemeket tartalmazó tömböket engedélyez. A JavaScript esetében lehetséges-e különböző típusú elemeket tartalmazó tömböt definiálni?
-
Vegyük az alábbi példát, ahol a
let item = { name: 'Tej', quantity: 1 }
egy objektum a bevásárlólistában. Hogyan lehetne ezt az objektumot úgy deklarálni, hogy tartalmazza a tétel árát (price)? -
Hogy lehet egy változó értékét a aktuális érték felére frissíteni egyetlen kódsorral?
Gondolkodtató feladatok
-
A következő kódban milyen érték jelenik meg a konzol kimenetén?
var value = "Global"; { value = "Lokáció"; } console.log(value);
-
Mi történik, ha a szorzási művelet egy vagy több operandusa egy sztring?
-
Hogy lehet eltávolítani a
Tojás
elemet acart
tömbből, ami az alábbi módon lett létrehozvalet cart = ['Tej', 'Kenyér', 'Tojás']
?
Összefoglalás
Ez a lecke a konstansok és változók alapvető használatát taglalja a JavaScriptben. A JavaScript egy dinamikusan tipizált nyelv, így a programozónak nem kell megadnia a változó típusát, mielőtt beállítja azt. Az alapvető műveletek helyes kimenetelének biztosítása érdekében azonban fontos ismerni a nyelv primitív típusait. Továbbá az olyan adatszerkezetek, mint a tömbök és az objektumok, kombinálják a primitív típusokat és lehetővé teszik a programozó számára, hogy komplexebb, összetettebb változókat hozzon létre. Ez a lecke a következő fogalmakat és eljárásokat veszi át:
-
Konstansok és változók
-
Változók hatóköre
-
Változók deklarálása a
var
és alet
segítségével -
Primitív típusok
-
Aritmetikai operátorok
-
Tömbök és objektumok
-
Típuskényszerítés és típuskonverzió
Válaszok a gyakorló feladatokra
-
A tömb egy olyan adatszerkezet, amely több programozási nyelvben is jelen van, némelyik azonban csak azonos típusú elemeket tartalmazó tömböket engedélyez. A JavaScript esetében lehetséges-e különböző típusú elemeket tartalmazó tömböt definiálni?
Igen, JavaScriptben lehetséges különböző primitív típusú elemeket tartalmazó tömböket definiálni, például sztringeket és számokat.
-
Vegyük az alábbi példát, ahol a
let item = { name: 'Tej', quantity: 1 }
egy objektum a bevásárlólistában. Hogyan lehetne ezt az objektumot úgy deklarálni, hogy tartalmazza a tétel árát (price)?let item = { name: 'Tej', quantity: 1, price: 4.99 };
-
Hogy lehet egy változó értékét a aktuális érték felére frissíteni egyetlen kódsorral?
Operandusként használhatjuk magát a változót,
value = value / 2
, vagy a rövidített operátorral/=
:value /= 2
.
Válaszok a gondolkodtató feladatokra
-
A következő kódban milyen érték jelenik meg a konzol kimenetén?
var value = "Global"; { value = "Lokáció"; } console.log(value);
Lokáció
-
Mi történik, ha a szorzási művelet egy vagy több operandusa egy sztring?
A JavaScript a
NaN
(Not a Number) értéket rendeli az eredményhez, jelezve, hogy a művelet érvénytelen. -
Hogy lehet eltávolítani a
Tojás
elemet acart
tömbből, ami az alábbi módon lett létrehozvalet cart = ['Tej', 'Kenyér', 'Tojás']
?A JavaScriptben a tömbök rendelkeznek a
pop()
metódussal, amely eltávolítja a lista utolsó elemét:cart.pop()
.