Kihagyás

9. gyakorlat

A gyakorlat anyaga

Ezen a gyakorlaton megtanuljuk, hogyan futtathatjuk a JavaScript nyelven írt szkriptjeinket terminálból a Node.js futtatókörnyezet segítségével. Szó lesz a nyelv fontosabb vezérlési szerkezeteiről, a függvényekről, valamint a stringekkel is részletesebben fogunk foglalkozni.

JavaScript futtatása terminálból

Az előző gyakorlaton a böngészős JavaScripttel ismerkedtünk meg. Ekkor a JavaScript kódunkat HTML kódba ágyaztuk be, majd azt a böngészőben található JavaScript Engine segítségével futtattuk.

A JavaScript kódjaink futtatásához viszont nem feltétlenül szükséges böngésző, hanem akár parancssorból is tudjuk ezeket futtatni (hasonlóképpen, mint ahogy azt a Python szkriptjeinkkel csináltuk).

Node.js telepítése

A terminálból való futtatáshoz a Node.js nevű futtatókörnyezetet fogjuk használni. Ezt erről a weboldalról szerezhetjük be. Töltsük le, majd telepítsük fel az LTS (Long Term Support) verziót!

A telepítés után nyissunk egy parancssort, és itt adjuk ki a node --version parancsot! Ha a parancs kimenete a telepített program verziószáma, akkor a telepítés sikeres volt.

Szkriptek futtatása Node.js segítségével

Hozzunk létre egy új JavaScript fájlt index.js néven, majd írjuk bele az alábbi kódot:

1
2
console.log("Hello!");
console.log("Ez a konzolablakon fog megjelenni.");

Mentsük el a szkriptet, majd parancssorban adjuk ki a node index.js parancsot abban a mappában, ahol a fájl található! A parancs segítségével lefuttatjuk az imént létrehozott szkriptünket, és máris láthatjuk annak kimenetét a terminál ablakon.

Kimenet

Hello! Ez a konzolablakon fog megjelenni.

Vezérlési szerkezetek

Az alábbiakban áttekintjük a JavaScript fontosabb vezérlési szerkezeteit.

Szelekciós vezérlés

JavaScriptben a szelekciós vezérlés megvalósítására az if, else, else if és switch utasításokat használjuk. Ezek szintaxisa és működése megegyezik a C-ben tanultakkal.

A vizsgálandó feltételek megadására az előző leckében tanult feltételes és logikai operátorokat használhatjuk.

Példa: Egy program, amely eldönti a felhasználóról, hogy nagykorú-e vagy sem

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let eletkor = 12;       // a felhasználó életkora

if (eletkor < 18) {
    console.log("Kiskorú vagy.");
    console.log("Még " + (18 - eletkor) + " év és nagykorú leszel.");
} else if (eletkor >= 20 && eletkor <= 29) {
    console.log("Huszonéves vagy.");
} else {
    console.log("Nagykorú vagy.");
}

Kimenet

Kiskorú vagy. Még 6 év és nagykorú leszel.

Példa: Egy program, amely kiírja egy érdemjegynek megfelelő szöveges értékelést

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
let jegy = 5;           // a kérdéses jegy

switch (jegy) {
    case 1: console.log("Elégtelen"); break;
    case 2: console.log("Elégséges"); break;
    case 3: console.log("Közepes"); break;
    case 4: console.log("Jó"); break;
    case 5: console.log("Jeles"); break;

    // ha a fentiek közül egyik esetre sem illeszkedünk, akkor a default ág fut le...
    default: console.log("Érvénytelen érdemjegy!");
}

Kimenet

Jeles

Egy kis érdekesség, hogy azokat a feltételeket, amelyek csupán egy if és egy else ágból állnak, a C-ből ismerős ternary operátor segítségével JavaScriptben is lerövidíthetjük.

Szintaxisa a szokásos: feltetel ? muvelet ha igaz : muvelet ha hamis.

Példa: A ternary operátorral lerövidíthetjük az if-else szerkezeteinket

1
2
3
4
5
6
7
8
9
// feltételvizsgálat ternary operátor használata nélkül

let szam = 42;

if (szam % 2 === 0) {
    console.log("Páros.");
} else {
    console.log("Páratlan.")
}
1
2
3
4
// ugyanez ternary operátor használatával

let szam = 42;
console.log(szam % 2 === 0 ? "Páros." : "Páratlan.");

Ismétléses vezérlés (Ciklusok)

JavaScriptben a while, do... while, illetve for utasításokat használjuk ismétléses vezérlés megvalósítására. Ezek ugyanúgy működnek, mint C-ben.

Példa: Írassuk ki az egész számokat 1-től 10-ig mindhárom ciklussal!

1
2
3
4
5
6
7
8
// while-ciklus

let i = 1;

while (i <= 10) {
    console.log(i);
    i++;
}
1
2
3
4
5
6
7
8
// do while-ciklus

let i = 1;

do {
    console.log(i);
    i++
} while (i <= 10);
1
2
3
4
5
// for-ciklus

for (let i = 1; i <= 10; i++) {
    console.log(i);
}

Megjegyzés: a for-ciklust használhatjuk a Pythonban tanultakhoz hasonló módon is, elemsorozatok bejárására. Ezzel a következő gyakorlaton ismerkedünk meg.

Függvények

Függvénydefiníció

JavaScriptben a function kulcsszóval definiálhatunk saját függvényeket. Ezt követően megadjuk a függvény nevét, majd zárójelek között a bementi paramétereket (ha vannak). A függvény törzsét kapcsos zárójel pár között adhatjuk meg.

1
2
3
function fuggvenyNeve(/* param1, param2, ... */) {
    // utasítások...
}

A függvényeinknek természetesen lehet visszatérési értéke is, ezt a return kulcsszó után adhatjuk meg.

1
2
3
function osszead(szam1, szam2) {
    return szam1 + szam2;
}

Érdemes megjegyezni, hogy a függvényen belül létrehozott változók függetlenül attól, hogy a var vagy let kulcsszóval deklaráljuk őket, minden esetben lokálisak lesznek a függvény törzsén belül. Ha a függvényen kívül akarunk rájuk hivatkozni, akkor hibát kapunk.

1
2
3
4
5
6
7
function egyKlasszFuggveny() {
    var valamiValtozo = 10;
    let valamiMasikValtozo = 20;
}

// console.log(valamiValtozo);              // HIBA!!
// console.log(valamiMasikValtozo);         // SZINTÉN HIBA!!

Függvényhívás

Ha egy függvényt meg szeretnénk hívni JavaScriptben, akkor azt a szokásos szintaxissal teketjük meg.

1
fuggvenyNeve(/* param1, param2, ... */);

A hívás során átadjuk a függvénynek a bemeneti paramétereket (feltéve ha a kérdéses függvény vár paramétert).

Ha a függvényhívás során nem adjuk meg valamelyik függvényparaméter értékét, akkor az adott paraméter az undefined speciális értéket veszi fel.

1
2
3
4
5
function info(nev, eletkor) {
    console.log(nev + " " + eletkor + " éves.");
}

info("Józsi");          // eletkor értéke: undefined

Kimenet

Józsi undefined éves.

Érdekes módon ha több paraméterrel hívunk meg egy függvényt, mint amennyi paramétert vár, akkor a JavaScript erre nem dob hibát. Ekkor a "fölösleges" paraméterek nemes egyszerűséggel figyelmen kívül lesznek hagyva.

1
2
3
4
5
function osszead(szam1, szam2) {
    return szam1 + szam2;
}

console.log(osszead(10, 20, 30, 40));   // a 30 és 40 paramétereket figyelmen kívül hagyjuk

Kimenet

30

Paraméterek meglétének ellenőrzése

Amint fentebb láthattuk, JavaScriptben gond nélkül megtehetjük azt, hogy a függvény egy adott paraméterének nem adunk át értéket a függvényhíváskor. Ez nem túl előnyös, jó lenne, ha ezt valahogyan le tudnánk kezelni.

Ha egy paraméter értékét nem adtuk meg, akkor az adott paraméter az undefined speciális értéket veszi fel. Ezt kihasználva már könnyedén le tudjuk ellenőrizni, hogy egy paraméter értékét megadták-e.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function koszon(nev) {
    if (nev === undefined) {        // ha a nev paramétert nem adták meg...
        console.log("Add meg annak a nevét, akinek köszönni szeretnél!");
    } else {
        console.log("Szia " + nev + "!");
    }
}

koszon();
koszon("János");

Kimenet

Add meg annak a nevét, akinek köszönni szeretnél! Szia János!

Default paraméterek

A Pythonban tanultakhoz hasonlóan JavaScriptben sincs function overload (még eltérő paraméterezés esetén sem). Ha két vagy több azonos nevű függvényünk van, akkor mindig a kódban legkésőbb definiált függvény lesz hívható.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
function hello() {
    console.log("Hello!");
}

function hello(nev) {
    console.log("Hello " + nev + "!");
}

hello();
hello("János");

Kimenet

Hello undefined! Hello János!

A fenti kódban két hello névre hallgató függvényünk is van, ezért a fentebb leírtak miatt a legutoljára definiált, egy paramétert váró hello(nev) függvény lesz hívható. Mivel a 9. sorban nem adtuk meg a nev paraméter értékét, ezért az az undefined értéket vette fel.

Szerencsére a Pythonból ismerős default függvényparaméterek JavaScriptben is léteznek. Ezek segítségével már el tudjuk érni, hogy egy függvényt többféle eltérő paraméterezés mellett is használhassunk.

Emlékeztetőül: a default paraméterek lényege, hogy a függvény bizonyos paramétereinek alapértelmezett értéket adunk a függvénydefiníció során. Ha a függvényhíváskor nem adjuk meg az adott paraméter értékét, akkor az az alapértelmezett értéket veszi fel.

1
2
3
4
5
6
function hello(nev="Senki") {
    console.log("Hello " + nev + "!");
}

hello();                // nev értéke: "Senki"
hello("János");         // nev értéke: "János"

Kimenet

Hello Senki! Hello János!

Mivel a függvényhíváskor a paraméterek átadása JavaScriptban is "balról jobbra" történik, ezért itt is fontos, hogy ha nem minden paraméternek adunk default értéket, akkor a default értékkel rendelkező paraméterek mindig a paraméterlista jobb oldalán szerepeljenek (azaz mindig az utolsó néhány paraméternek kell default értéket adnunk).

1
2
3
4
5
6
7
function info(nev, eletkor=20, foglalkozas="programozó") {
    console.log(nev + " " + eletkor + " éves és " + foglalkozas + ".");
}

info("Józsi");
info("Józsi", 50);
info("Józsi", 50, "asztronauta");

Kimenet

Józsi 20 éves és programozó. Józsi 50 éves és programozó. Józsi 50 éves és asztronauta.

Callback függvények

JavaScriptben gyakran előfordul, hogy egy függvényt egy másik függvény paramétereként használunk fel. Az ilyen függvényt nevezzük callback függvénynek.

A callback függvényt természetesen meg is tudjuk hívni abban a függvényben, amely paraméterül kapja azt. Ezt a meghívást feltételhez is köthetjük, ha szeretnénk.

Példa: Az ejszakaNeZenelj függvény második paramétereként átadott zenetJatszik függvény egy callback függvény, amit a 13. sorban meghívunk

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// ő lesz majd a callback függvényünk, amit meghívunk egy másik függvényben

function zenetJatszik() {
    console.log("Hadd szóljon a Rock and Roll!");
}

// egy függvény, amelynek a callback nevű paramétere szintén egy függvény lesz

function ejszakaNeZenelj(ora, callback) {
    if (ora >= 22 || ora <= 6) {
        console.log("Éjszaka van, alszanak a szomszédok!");
    } else {
        callback();     // callback függvény meghívása
    }
}

// függvényhívás: a callback függvény a zenetJatszik függvény lesz

ejszakaNeZenelj(16, zenetJatszik);

Kimenet

Hadd szóljon a Rock and Roll!

JavaScriptben érdemes lehet leellenőrizni, hogy a callback függvényünk ténylegesen egy függvény-e. Ezt a typeof kulcsszóval tudjuk egyszerűen megtenni.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
function myCallback(param) {
    console.log("Callback függvény meghívva " + param + " paraméterrel.");
}

function myFunction(callback) {
    if (typeof callback === "function") {   // típusellenőrzés...
        callback("kiscica");
    }
}

myFunction(myCallback);

Kimenet

Callback függvény meghívva kiscica paraméterrel.

JavaScript függvények egyéb megadási módjai

Anonim függvények

JavaScriptben a hagyományos függvénydefiniálás mellett a függvényeket egy kifejezésként is definiálhatjuk. Ezeket a függvény kifejezéseket akár egy változóban is eltárolhatjuk.

1
let osszead = function (a, b) { return a + b; }

Miután a példában a függvény kifejezésünket eltároltuk az osszead változóban, a változót használhatjuk függvényként.

1
2
3
let osszead = function (a, b) { return a + b; }
let osszeg = osszead(10, 5);        // függvényhívás
console.log(osszeg);

Kimenet

15

Az ilyen módon létrehozott függvényeket anonim függvénynek is nevezik, hiszen ezek nem rendelkeznek függvénynévvel. Nincs is szükség rá, hogy névvel rendelkezzenek, hiszen az őket tároló változó nevével tudjuk őket meghívni.

Egy fontos különbség a hagyományos úton definiált függvények és az anonim függvények között, hogy az anonim függvények csak akkor jönnek létre, amikor a vezérlés eljut hozzájuk, és csupán ekkortól lesznek használhatóak. Ezzel szemben a hagyományos módon definiált függvények már a definiálásuk előtt is elérhetők, hívhatók a kódban.

1
2
3
4
5
6
7
8
hello1();       // a hello1 függvény már a definíciója előtt is hívható

function hello1() {
    console.log("Hello World!");
}

// hello2();    // HIBA!! - itt a hello2 anonim függvény még nem jött létre
let hello2 = function() { console.log("Hello World!"); }

Kimenet

Hello World!

Arrow function-ök

Az ECMAScript 6 (ES6) szabványban bevezették az úgynevezett arrow function-öket az anonim függvények tömörebb megadására.

A szintaxisuk a következő:

1
let myArrowFunction = (/* param1, param2, ... */) => { /* ... */ };

Ha a függvényünk nem vár egyetlen paramétert sem, akkor a => előtti zárójelpárt üresen hagyjuk. Ha a függvényünk egyetlen paramétert vár, akkor a zárójeleket el szoktuk hagyni.

Példa: 0, 1 és 2 paramétert váró arrow function-ök

1
2
3
4
5
6
7
let koszon = () => { console.log("Hello World!"); }
let kedvencFagyi = iz => { console.log("A kedvenc fagyiízünk: " + iz); }
let osszead = (a, b) => { return a + b; }

koszon();
kedvencFagyi("csokoládé");
console.log(osszead(10, 5));

Kimenet

Hello World! A kedvenc fagyiízünk: csokoládé 15

Bővebben a stringekről

Stringek megadása

A stringeket leggyakrabban aposztrófok ('...') vagy idézőjelek ("...") között szoktuk megadni. A két megadási mód között lényegi különbség nincs.

Több soros szövegeket backtick karakterek (AltGr + 7) között adhatunk meg.

1
2
3
4
let dalszoveg = `Never gonna give you up
Never gonna let you down 
Never gonna run around
And desert you`

Stringek összefűzése

A stringek összefűzése a + (plusz) operátorral történik.

1
2
let szoveg = "Java" + "Script";
console.log(szoveg);

Kimenet

JavaScript

Stringek hossza

JavaScriptben egy string hosszát a length property-vel tudjuk lekérdezni.

1
2
let szoveg = "JavaScript";
console.log(szoveg.length);

Kimenet

10

Karakterek indexelése

A stringek karaktereit JavaScriptben is a más nyelvekből ismerős szögletes zárójel operátorral indexelhetjük: szoveg[index]. A karakterek indexelése itt is 0-tól kezdődik.

1
2
3
4
5
let szoveg = "tüttyölt ratyli";

console.log("A 0. indexű karakter: " + szoveg[0]);
console.log("A 4. indexű karakter: " + szoveg[4]);
console.log("Az utolsó karakter: " + szoveg[szoveg.length - 1]);

Kimenet

A 0. indexű karakter: t A 4. indexű karakter: y Az utolsó karakter: i

Fontos megjegyezni, hogy a Pythonban tanult negatív indexelés, illetve intervallumos indexelés JavaScriptben nem működik! Amennyiben alul- vagy túlindexeljük a stringet, undefined értéket kapunk.

1
2
3
4
let szoveg = "kenyér";

console.log(szoveg[800]);
console.log(szoveg[-1]);

Kimenet

undefined undefined

Immutable adattípus

A string adattípus JavaScriptben is immutable, tehát a szövegek kezdeti értéke nem változtatható meg.

1
2
3
4
let szoveg = "kecske";
szoveg[0] = "f";                // ennek JavaScriptben nincs hatása!

console.log(szoveg);

Kimenet

kecske

Stringkezelő függvények

JavaScriptben rengeteg beépített stringkezelő függvényt használhatunk. Tekintsük át ezek közül a kurzus szempontjából a legfontosabbakat!

  • s.toLowerCase(): csupa kisbetűssé alakítja az s stringet
  • s.toUpperCase(): csupa nagybetűssé alakítja az s stringet
  • s.startsWith(v): igazat ad vissza, ha az s string a v értékkel kezdődik
  • s.endsWith(v): igazat ad vissza, ha az s string a v értékre végződik
  • s.substr(start, length): visszaadja az s stringből egy részstringet, a start indexű karakterétől kezdve, length karakteren keresztül
  • s.indexOf(text): visszaadja a text szöveg legelső előfordulásának a kezdőindexét az s stringen belül (-1-et ad vissza, ha a keresett szöveg nem szerepel az s stringben)
  • s.replace(old, new): lecseréli az s stringben a legelső old részstringet a new szövegre
  • s.trim(): eltávolítja a whitespace karaktereket az s string elejéről és végéről
  • s.split(delim): feldarabolja az s stringet delim karakterek mentén (egy tömböt ad vissza)
  • ...

Példa: Stringkezelő függvények használata

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
let szoveg = "    A citromos fagyi a legjobb fagyi        ";

szoveg = szoveg.trim();     // whitespace eltávolítása a szöveg elejéről és végéről

console.log(szoveg.toLowerCase());      // kisbetűsítés
console.log(szoveg.toUpperCase());      // nagybetűsítés
console.log(szoveg.endsWith("fagyi"));  // a "fagyi" stringre végződik-e a szöveg
console.log(szoveg.substr(0, 8));       // az első 8 karakter
console.log(szoveg.replace("fagyi", "süti"));   // részstring lecserélése (csak az első előfordulást!)

if (szoveg.indexOf("fagyi") >= 0) {     // részstring előfordulásának vizsgálata
    console.log("Szerepel a szövegben fagyi!");
} else {
    console.log("A szövegben nem szerepel fagyi!");
}

const szavak = szoveg.split(" ");       // feldarabolás szóközök mentén
console.log(szavak);

Kimenet

a citromos fagyi a legjobb fagyi A CITROMOS FAGYI A LEGJOBB FAGYI true A citrom A citromos süti a legjobb fagyi Szerepel a szövegben fagyi! [ 'A', 'citromos', 'fagyi', 'a', 'legjobb', 'fagyi' ]

Kérdés: A replace() a kérdéses részstringnek csak a legelső előfordulását cseréli le a szövegben. Hogyan lehet elérni, hogy a fagyi szöveg összes előfordulását lecseréljük a süti szövegre?

Válasz:

1
2
3
4
5
6
7
let szoveg = "A citromos fagyi a legjobb fagyi";

while (szoveg.indexOf("fagyi") >= 0) {          // amíg szerepel a szövegben a "fagyi" részstring...
    szoveg = szoveg.replace("fagyi", "süti");   // ...folyamatosan lecseréljük "süti"-re
}

console.log(szoveg);

Kimenet

A citromos süti a legjobb süti

Kiegészítés: template stringek

Ha egy szövegen belül be szeretnénk helyettesíteni bizonyos változók értékeit, akkor erre eddig a hagyományos string összefűzést használtuk.

1
2
let nev = "Józsi", eletkor = 20, foglalkozas = "programozó";
console.log(nev + " egy " + eletkor + " éves " + foglalkozas + ".");

Ha nagyon sok behelyettesítendő értékünk van, akkor egy idő után ez a módszer fárasztóvá válhat. Szerencsére az ECMAScript 6-os szabványban bevezették az úgynevezett template stringeket, amelyek segítségével a fenti kiíratás egyszerűbben megoldható.

A template stringeket backtick-ek (AltGr + 7) között adjuk meg. Használatuk során nem kell megszakítanunk a szövegünket a változók értékének behelyettesítésekor (mint az összefűzéses módszernél), a behelyettesíteni kívánt kifejezés értékét egyszerűen ${ }-be írjuk.

1
2
let nev = "Józsi", eletkor = 20, foglalkozas = "programozó";
console.log(`${nev} egy ${eletkor} éves ${foglalkozas}.`);  // ez talán így kényelmesebb :)

Feladatok

Az anyagrészhez tartozó gyakorló feladatsor elérhető itt.


Utolsó frissítés: 2020-11-03 20:48:36