Alkalmazások fejlesztése

1. előadás

Horváth Győző
Egyetemi adjunktus
1117 Budapest, Pázmány Péter sétány 1/c., 2.420-as szoba
Tel: (1) 372-2500/1816
horvath.gyozo@inf.elte.hu

Tartalomjegyzék

  • Követelmények ismertetése
  • JavaScript nyelvi elemek
  • Fejlesztői környezetek
  • Gyakorlati tudnivalók

Követelmények

Lásd a tárgy honlapját

Kliens-szerver architektúrák

Egygépes alkalmazások

  • A program teljes egészében a munkaállomáson fut.
  • Az adatok is ugyanitt tárolódnak.
  • Egyszerre csak egy felhasználó használhatja az alkalmazást.
  • Hálózati kapcsolat nincs, vagy nem jellemző, esetleg korlátozott. Az adatszinkronizáció meglehetősen nehézkes.

Egyszerű kliens-szerver alkalmazások

Többrétegű hálózati alkalmazások

Alkalmazások fejlesztése tárgy

  • Többrétegű webalkalmazások készítése
    • Tervezés
    • Implementálás
    • Tesztelés
    • Dokumentálás
  • Webes alkalmazások magas szintű megközelítése (felülről lefelé építkezés)
  • Kicsit a webes szakdolgozatok előkészítése

Választott technológiák

  • Keretrendszerek használata (ahol lehet)
  • Szerveroldal
    • sokféle lehetőség, szinte bármilyen nyelv
    • kiforrott megoldások
  • Kliensoldal
    • JavaScript (szinte kizárólag)
  • Használjunk egy nyelvet!
  • --> JAVASCRIPT

JavaScript

Története

  • 1995: NetScape cég, Brendan Eich
  • Szabványosítás: ECMAScript
  • 1996-1999: a nyelv fejlődése a 2. böngészőháború során (ES3)
  • 2000-2006: semmi (szerveroldali technológiák fejlődnek)
  • 2006: AJAX
  • 2006-: a nyelv újrafelfedezése, modern programozási paradigmák kialakulása
  • 2011: ECMAScript 5.1
  • 2015: ECMAScript 6/ECMAScript 2015

Fejlesztőeszközök

  • Futtatókörnyezet
  • Szerkesztő
  • Kisegítő eszközök
  • Dokumentáció

Futtatókörnyezet

  • Böngészők (hagyományosan)
    • <script> elem
    • JavaScript konzol
  • Parancssor (Node.js)
    • konzol

    • fájl

Szerkesztők

  • Text editorok
  • (Notepad++)
  • Sublime text 3
  • Atom
  • Brackets
  • Visual Studio Code
  • WebStorm
  • Webes sandboxok (jsfiddle, jsbin)
  • Web IDE (Cloud9)

Kisegítő eszközök

  • Böngésző
    • fejlesztési eszköztárak
    • további bővítmények
  • Parancssor
    • számos telepíthető program (ld. később a félévben)

Dokumentáció

Népszerűség

  • A világ legelterjedtebb nyelve
  • kliensoldalon/szerveroldalon
  • böngészőben/parancssorban/asztali alkalmazás
  • 2D/3D játékok
  • operációs rendszerek kisalkalmazásai
  • beépülő rendszerek

JavaScript nyelvi elemei

Mintaként szolgáló nyelvek

  • C és Java: szintaxis
  • Scheme: funkcionális programozási nyelv
  • Self: prototípus alapú objektum-orientált nyelv
  • HyperCard: hipermédia rendszer (eseménykezelés)

JavaScript

  • dinamikus tipizált
  • interpretált
  • szkriptnyelv

További jellemzők

  • Kis és nagybetűk különböznek
  • Nincs főprogram (main)
  • Nincs input/output
  • Nincs fájlkezelés
  • Objektumorientált
  • Prototípusos
  • Automatikus pontosvessző beszúrás

Megközelítés

  1. Szintaxis: hasonlósági alapon
  2. Eltérések

Egyszerű típusok

//Number (szám)
12
12.34

//String (szöveg)
'Szöveg'
"Szöveg"
'Idézőjelben "így" macsakörmölök'
"Macskakörömben 'így' idézek"
'Idézőjelben \' idézőjel'
"Macskakörömben \" macskaköröm"
'Escape: \t \n \\ '

//Boolean (logikai)
true
false

null        //null

undefined   //undefined

Összetett típusok

//Array (tömb)
[
    'alma',
    'körte',
    'barack'
]

//Object (objektum)
{
    nev: 'Dávid',
    kor: 6
}

Változók

  • var kulcsszó
  • elhagyásával --> globális változó
var i = 1;
var x = [2, 6, 3, 1];
var a;  //undefined

Operátorok

  • ld. Java
  • ===, !==
12 ==  '12'     //true
12 === '12'     //false

Vezérlési szerkezetek

  • ld. Java
  • if, else
  • for, while, do-while
  • switch, case, break

Függvények

//Függvény általános formája
function fvnev(par1, par2) {
    utasítások;
    return visszatérési érték;
}
  
//Például
function negyzet(x) {
    return x * x;
}
negyzet(3);     // => 9

Változók láthatósága

  • Függvényen belül a var kulcsszó lokális változó
  • Function scope van block scope helyett!
var alma = 'piros';

function fv() {
    //var korte;
    console.log(alma);      //=> piros
    console.log(korte);     //=> undefined
    if (true) {
        var korte = 'sarga';
    }
}

fv();

console.log(korte);         //=> ReferenceError

Objektumok

Objektumok tulajdonságai

  • név-érték párok gyűjteménye
    • tulajdonságok (adattagok)
    • metódusok
var obj = {
    tulajdonsag: 1,
    'ez is tulajdonság': 2,
    metodus: function () {
        console.log(this.tulajdonsag);
    }
};

obj.tulajdonsag
obj['ez is tulajdonsag']
obj.metodus()

Két alappillér

  • dinamikus objektumok
  • prototípus-objektum

Dinamikus objektumok

//Objektum megadása
var obj = {
    a: 1,
    b: 2
};

//Minta: új tulajdonság felvételére
obj.c = 3;      

//Minta: tulajdonság lekérdezése (olvasás)
obj.a    === 1          // obj.név formában történő olvasás'
obj['a'] === 1,         // obj['név'] formában történő olvasás"
obj.d    === undefined  //Nem létező névre hivatkozva undefined-ot kapunk

//Minta: tulajdonság értékének módosítása
obj.b = 42;   

//Minta: tulajdonság törlése
delete obj.c;

Prototípus-objektum

Prototípuslánc

A prototípus beállítása és lekérdezése

//A prototípuslánc kialakítása
var obj2 = Object.create(obj1);

//Tesztek
obj1.isPrototypeOf(obj2)                //obj1 szerepel obj2 prototípusláncában
Object.getPrototypeOf(obj2) === obj1    //obj2 prototípusa obj1

Írás és olvasás egy objektumon

  • Olvasás: végignézi a prototípusláncot
  • Írás: mindig az adott objektumon

Objektumok létrehozása konstruktorfüggvénnyel

function Person(name) {
    this.name = name;
}
Person.prototype.describe = function () {
    return 'Person called '+this.name;
};

var jim = new Person('Jim');
jim.name        //'Jim'
jim.describe()  //'Person called Jim'

Öröklés

function Employee(name, title) {
    Person.call(this, name);
    this.title = title;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;
Employee.prototype.describe = function () {
    return Person.prototype.describe.call(this)+' ('+this.title+')';
};

var jane = new Employee('Jane', 'CTO');
jane.describe()     //'Person called Jane (CTO)'

Öröklés segédfüggvénnyel

function subclasses(SubC, SuperC) {
    var subProto = Object.create(SuperC.prototype);
    // Save `constructor` and, possibly, other methods
    copyOwnPropertiesFrom(subProto, SubC.prototype);
    SubC.prototype = subProto;
    SubC._super = SuperC.prototype;
};

function Employee(name, title) {
    Employee._super.constructor.call(this, name);
    this.title = title;
}
Employee.prototype.describe = function () {
    return Employee._super.describe.call(this)+' ('+this.title+')';
};
subclasses(Employee, Person);

Tömbök

Tömb

  • könnyen iterálható lista jellegű objektum
  • indexelési tulajdonsággal
var uresTomb = [];
var tomb = [12, 'alma', true];
tomb[0];        // => 12;
tomb[1];        // => 'alma';
tomb[2];        // => true;
tomb.length     // => 3

//Módosítás
tomb[0] = 13;

//Bővítés
tomb[tomb.length] = 'uj';
tomb[100] = 'messze';
tomb.length;    // => 101
tomb[99];       // => undefined

//Törlés (méret nem változik)
delete tomb[1];
tomb[1];        // => undefined
tomb.length;    // => 101

Tömbműveletek

  • pop(), push(e), shift(e), unshift(): végéről, végére, elejére, elejéről.
  • reverse(): megfordítja a tömb elemeit.
  • splice(honnan, mennyit): kivág a tömbből elemeket. Ezzel lehet úgy törölni, hogy a tömb hossza csökkenjen.
  • join(szeparátor): a tömb elemeit a szeparátor-ral elválasztva szöveggé fűzi össze.

Tömbműveletek

  • forEach: iterálás
  • map: másolás
  • filter: kiválogatás
  • every: optimista eldöntés
  • some: eldöntés
  • reduce: összegzés
var numbers = [1, 2, 3];
var oddNumbers = numbers.filter(function (item) {
    return item % 2 !== 0;
});
oddNumbers;     //[1, 3]

Iterálás

var gyumolcsok = [
  'alma',
  'korte',
  'szilva'
];

//A gyümölcsök kiírása a konzolra
for (var i = 0; i < gyumolcsok.length; i++) {
  console.log(gyumolcsok[i]);
}

//vagy
gyumolcsok.forEach(function (gyumolcs) {
    console.log(gyumolcs);
});

Adatszerkezetek modellezése

Tipikus szerkezetek

//C++ vector --> JavaScript tömb
var kutyuk = [
  'telefon',
  'fülhallgató',
  'pendrive',
  'e-könyv olvasó'
];

//C++ struct --> JavaScript objektum
var hallgato = {
  nev: 'Mosolygó Napsugár',
  neptun: 'kod123',
  szak: 'Informatika BSc'
};

Tipikus szerkezetek

//Rekordok tömbje
var hallgatok = [
  {
    nev: 'Mosolygó Napsugár',
    neptun: 'kod123',
    szak: 'Informatika BSc'
  },
  {
    nev: 'Kék Ibolya',
    neptun: 'kod456',
    szak: 'Informatika BSc'
  }
];

JSON

  • JavaScript Object Notation
  • A JavaScript literálformáira épülő adatleírási formátum
  • Népszerű!
  • JSON.parse(): szövegből adatszerkezet
  • JSON.stringify(): adatszerkezetből szöveg

JSON

[
    {
        "nev":"Mosolygó Napsugár",
        "neptun":"kod123",
        "szak":"Informatika BSc",
        "targyak":[
            "Programozás",
            "Webfejlesztés 2.",
            "Számítógépes alapismeretek"
        ]
    },
    {
        "nev":"Kék Ibolya",
        "neptun":"kod456",
        "szak":"Informatika BSc",
        "targyak":[
            "Programozás",
            "Webfejlesztés 2.",
            "Diszkrét matematika",
            "Testnevelés"
        ]
    }
]

Függvények

Függvénylétrehozás

//Deklaráció
function osszead(a, b) {
    return a + b;
}

//Függvénykifejezés
var osszead = function(a, b) {
    return a + b;
}

Függvényliterál

function [név]([param [, param [..., param]]]) {
   utasítások
}

Függvény mint első osztályú objektum

  • speciális objektum meghívható kóddal
  • bármilyen kifejezésben szerepelhet
    • értékadás jobb oldalán (ld. a függvénylétrehozás)
    • objektum tulajdonságaként (metódus)
    • függvényparaméterként
    • függvény visszatérési értékeként (függvénygenerátor)

Függvény mint paraméter

function kereses(x, T) {
    var i = 0;
    while (i < x.length && !T(x[i])) {
        i++;
    }
    return {
        vane: i < x.length,
        sorsz: i
    };
}

function negativE(p) {
    return p < 0;
}
  
var tomb = [1, 3, -2, 8];
kereses(tomb, negativE);

Függvény mint visszatérési érték

function muveletKeszito(op) {
    if (op === '+') {
        return function (a, b) {
            return a + b;
        };
    }
    else if (op === '*') {
        return function (a, b) {
            return a * b;
        };
    }
}
  
//Összeadó függvény készítése
var muvelet = muveletKeszito('+');
muvelet(10, 32);    //42
  
//Szorzó függvény készítése
var muvelet = muveletKeszito('*');
muvelet(10, 32);    //320

Closure

Minden függvény kapcsolatban marad az őt tartalmazó függvény változóival, még akkor is, ha a külső függvény véget ér.

function createIncrementor(start) {
    return function () {  // (1)
        start++;
        return start;
    }
}

var inc = createIncrementor(5);
inc()   // 6
inc()   // 7
inc()   // 8

ECMAScript 6

ECMAScript 6 (ECMAScript 2015)

Fejlesztőkörnyezet

Lehetőségek

  • Böngésző JavaScript konzol
  • Szerkesztő + parancssori futtatás: node fájlnév
  • Webes sandbox: jsbin
  • Webes REPL: Babel
  • Webes IDE: Cloud9

Webes IDE

  • Github account létrehozása
  • Belépés Cloud9-ba Github accounttal
  • Create new workspace (Node.js)
  • Webes terminálablakban: node fájlnév

Feladatok

  1. Adott kapcsolatok tára. Egy kapcsolatról tároljuk a nevét, e-mail címét, telefonszámát. Definiáld a szükséges adatszerkezetet, majd írj egy függvényt, amely visszaadja azokat a kapcsolatokat, amelyeknek neve tartalmaz egy paraméterként megadott szövegrészletet. A megoldást, ha tudod, oldd meg ES6-ban is!