Základy programovania v JavaScripte
Záverečná lekcia
Milan Herda, 03/2023
Čo nás dnes čaká
- vybrané vlastnosti z ES2015
- opakovanie
- tipy na štúdium
- kde sa dajú využiť znalosti
- vyrobíme si certifikát
Vybrané vlastnosti z JS verzie ES2015
Arrow funkcie
- kratší zápis
- uchovávanie kontextu (this, arguments)
Arrow funkcie - kratší zápis
var pow = function (arg) {
return arg * arg;
};
const pow = (arg) => {
return arg * arg;
};
const pow = (arg) => arg * arg;
// Pozor, zátvorky okolo argumentov sa dajú odobrať
// iba v prípade jednoargumentovej funkcie
// Funkcia bez argumentov musí mať zátvorky uvedené!
const getName = () => 'zelenina';
const pow = arg => arg * arg;
Arrow funkcie - zdieľanie kontextu
const tyrion = {
name: 'tyrion',
tags: ['piť', 'nadávať', 'veci'],
printKnowledge: function () {
this.tags.forEach(function (tag) {
console.log(this.name + ' vie ' + tag);
});
}
};
tyrion.printKnowledge();
Skúste tento kód opraviť v starom JS (bez arrow funkcie)
Arrow funkcie - zdieľanie kontextu
const tyrion = {
name: 'tyrion',
tags: ['piť', 'nadávať', 'veci'],
printKnowledge: function () {
const that = this;
this.tags.forEach(function (tag) {
console.log(that.name + ' vie ' + tag);
});
}
};
tyrion.printKnowledge();
Starý JS: pomocná premenná "that"
Arrow funkcie - zdieľanie kontextu
const tyrion = {
name: 'tyrion',
tags: ['piť', 'nadávať', 'veci'],
printKnowledge: function () {
this.tags.forEach((tag) => {
console.log(this.name + ' vie ' + tag);
});
}
};
tyrion.printKnowledge();
Nový JS: array funkcia
Rozšírené objektové literály
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';
const fero = {};
/* Pre objekt fero:
* - vytvorte property name a lastName,
* ktoré budú mať hodnoty z premenných vyššie
* - vytvorte metódu foo, ktorá vráti reťazec 'metóda foo'
* - vytvorte property, ktorej názov je poskladaný z x a y.
*/
console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
Rozšírené objektové literály
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';
const fero = {
name: name,
lastName: lastName,
// vytvorte metódu foo, ktorá vráti reťazec 'metóda foo'
// vytvorte property, ktorej názov je poskladaný z x a y.
};
console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
V starom JS
Rozšírené objektové literály
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';
const fero = {
name: name,
lastName: lastName,
foo: function () {
return 'metóda foo';
},
// vytvorte property, ktorej názov je poskladaný z x a y.
};
console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
V starom JS
Rozšírené objektové literály
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';
const fero = {
name: name,
lastName: lastName,
foo: function () {
return 'metóda foo';
},
};
fero[x + y] = 'počítaná property';
console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
V starom JS
Rozšírené objektové literály
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';
const fero = {
name,
lastName,
foo() {
return 'metóda foo';
},
[x + y]: 'počítaná property',
};
console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
V novom JS
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';
const fero = {
name,
lastName,
foo() {
return 'metóda foo';
},
[x + y]: 'počítaná property',
};
console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
const name = 'Ferko';
const lastName = 'Mrkvička';
const x = 'abc';
const y = 'def';
const fero = {
name: name,
lastName: lastName,
foo: function () {
return 'metóda foo';
},
};
fero[x + y] = 'počítaná property';
console.log(fero.name);
console.log(fero.lastName);
console.log(fero.foo());
console.log(fero.abcdef);
Destructuring - polia
const [x, y] = [1, 2];
const pole = ['agát', 'blýskavica', 'cieľovníci'];
const [a, , c] = pole;
const [foo, bar, baz = 33] = [11, 22];
// výmena hodnôt dvoch prvkov
let [var1, var2] = ['value 1', 'value 2'];
[var2, var1] = [var1, var2];
Destructuring - objekty
const obj = {
foo: 1,
bar: 2,
baz: 3,
};
const { foo, baz } = obj;
// prípadne pod iným názvom
const { foo: aliasFoo, baz } = obj;
// default hodnoty
const { foo, xyz = 42 } = obj;
Destructuring - objekty
// argumenty funkcie
const params = {
logger: 'console',
isDev: true,
};
foo(params);
const foo = function ({ isDev, logger }) {
console.log(logger);
console.log(isDev);
};
Opakovanie
Algoritmus a algoritmizácia
Algoritmus je postup riešenia problému
Algoritmizácia je vytváranie tohto postupu
Najefektívnejším spôsobom algoritmizovania je postupné rozkladanie problému na menšie časti. Tzv. Divide & Conquer
Počítač neurobí to, čo chcem.
Urobí to, čo mu poviem.
Programovací jazyk
Vysoko formalizovaný jazyk so striktnými pravidlami, pomocou ktorého vieme zapísať algoritmus
Základné stavebné bloky programovacieho jazyka
- dáta (premenné, konštanty)
- funkcie
Premenné
Slúžia na ukladanie dát v pamäti počas behu programu
Deklarujeme pomocou kľúčových slov
- var
- let
- const
Typy premenných
Primitívne
- boolean
- číslo
- reťazec
- null
- undefined
Zložené
- objekt
- pole
- funkcia
Funkcie
Slúžia na rozdeľovanie algoritmu na menšie časti
Je dôlezité ich trefne pomenovávať
function abc(param) {
console.log(param);
}
const def = function (param) {
console.log(param);
}
const ghi = (param) => {
console.log(param);
}
Pokiaľ je funkcia súčasťou objektu, hovoríme jej metóda.
Podmienky
Slúžia na podmienené vykonávanie kódu
if (podmienka) {
príkaz();
}
if (podmienka) {
príkaz1();
} else if {
príkaz2();
} else {
príkaz3();
}
if (podmienka1 && podmienka2) {
príkaz();
}
if (podmienka1 || podmienka2) {
príkaz();
}
Cykly
Slúžia na opakované vykonávanie kódu
while (podmienka) {
príkaz();
}
do {
príkaz();
} while (podmienka);
for (let i = 0; i < 10; i += 1) {
príkaz();
}
for (let vlastnost in objekt) {
console.log(objekt[vlastnost]);
}
Operátory
Pomocou operátorov robíme operácie s dátami
- priraďovacie (=, +=)
- matematické (+, -, *, /, %, **)
- logické (&&, ||)
- na prácu s reťazcami (+)
- ...
Tipy na štúdium
Základný nástroj pre akýkoľvek projekt
git
Chcem programovať krátke skripty pre ecom nástroje
- HTML + CSS
- DOM model
Témy a nástroje:
Chcem programovať webstránky
Témy a nástroje:
Chcem programovať aplikácie pre mobily
- React Native
- testovanie
- HTTP REST API a/alebo GraphQL
- databázy (Firebase, SQLite, MariaDB/MySQL)
Témy a nástroje:
Chcem programovať aplikácie pre PC
Témy a nástroje:
- všetko z tipov pre webstránky :)
- a navyše Electron
Chcem programovať hry
Témy a nástroje:
- podľa cieľového prostredia (web, mobil, PC)
- navyše:
- game engine
- websockets
- základy matematiky a fyziky (vektory, sila, rýchlosť)
- návrhové vzory (Design Patterns)
- základy hernej "umelej inteligencie"
Tipy na kurzy, videá, knihy a pod.
Kurzy a videá
Douglas Crockford
JavaScript: The Good Parts
- ✅ veľmi dobrá pre získanie hlbšieho pochopenia JavaScriptu
- ❌ nie úplne pre začiatočníkov
- ❌ niektoré neaktuálne veci
Josh Goldberg
Learning Typescript
TypeScript je nadstavba JavaScript-u, ktorá mu dodáva striktnú typovosť.
Kde využiť získané znalosti mimo programovania?
Algoritmizácia
Metóda "rozdeľuj a panuj" vie pomôcť v riešení problémov a životných situácii všeobecne.
Lepšie porozumenie fungovaniu webstránok a softvéru všeobecne
Lepšie porozumenie práci programátorov
Lepšie porozumenie pozadiu pri práci s nocode nástrojmi (Power Automate, Apps, BI...)
Občasné skriptovanie
- skripty pre GTM, ecom nástroje alebo malé pluginy pre WordPress a pod.
- spracovávanie dát z Excelu
- automatizovanie opakujúcich sa úloh
Tvorba modov do hier
Certifikát
Úloha: naprogramujte generátor certifikátov o ukončení školenia pre každého účastníka
- certifikát bude obrázok v SVG formáte
- SVG markup vygeneruje váš kód v JavaScript-e
Rýchlokurz SVG
<svg height="210mm" width="297mm" viewBox="0 0 2100 2970">
<rect
x="100"
y="100"
width="1900"
height="2770"
fill="green"
stroke="black"
stroke-width="10"
/>
<text
x="1486"
y="1050"
text-anchor="middle"
font-size="35mm"
>
Základy programovania v JavaScripte
</text>
<line
x1="1770"
y1="1600"
x2="2670"
y2="1600"
stroke="black"
stroke-width="3"
/>
</svg>
// súbor certificate.js
function generateCertificate() {
const height = 2100;
const width = 2970;
const centerX = width / 2;
const centerY = height / 2;
const quarterWidth = width / 4;
return `
<svg height="210mm" width="297mm" viewBox="0 0 ${width} ${height}" xmlns="http://www.w3.org/2000/svg"
>
<rect x="50" y="50" width="2870" height="2000" stroke="black" fill="none" stroke-width="1" rx="15" />
<text x="${centerX}" y="250" class="title" text-anchor="middle">Potvrdenie o absolvovaní kurzu</text>
<text x="${centerX}" y="550" text-anchor="middle" class="name">Ferko Mrkvička</text>
<text x="${centerX}" y="750" text-anchor="middle" class="normal">úspešne absolvoval kurz</text>
<text x="${centerX}" y="${centerY}" class="course-title" text-anchor="middle">Základy programovania v JavaScripte</text>
<rect x="1770" y="1450" width="900" height="150" fill="white" class="signature-box"/>
<line x1="1770" y1="1600" x2="2670" y2="1600" stroke="black" stroke-width="3" />
<text x="${
quarterWidth * 3
}" y="1680" text-anchor="middle" class="normal">Lektor: Milan Herda</text>
<text x="${
quarterWidth * 3
}" y="1750" text-anchor="middle" class="small">Dátum: 21.2.2023</text>
<text x="450" y="1500" text-anchor="start" class="normal">Dĺžka kurzu: 45 hodín</text>
<text x="450" y="1600" text-anchor="start" class="normal">Forma: prezenčná</text>
<text x="150" y="1950" text-anchor="start" class="footer">https://www.programatorske-skolenia.sk/</text>
<text x="2820" y="1950" text-anchor="end" class="footer">https://www.perunhq.org/</text>
</svg>
`;
}
document.querySelector('#app').innerHTML = generateCertificate();
Stiahnite si túto funkciu pre generovanie certifikátu
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Certifikát</title>
<style>
svg {
border: solid 1px black;
}
.title {
font-size: 25mm;
font-weight: bold;
}
.course-title {
font-size: 35mm;
font-weight: bold;
}
.name {
font-size: 30mm;
font-weight: bold;
}
.normal {
font-size: 15mm;
}
.small {
font-size: 12mm;
}
.footer {
font-size: 8mm;
fill: grey;
}
.signature-box: {
border-bottom: solid 1px black;
}
</style>
</head>
<body>
<div id="app"></div>
<script src="./certificate.js"></script>
</body>
</html>
Môže byť použitá napríklad v takomto HTML súbore
Úloha: Upravte funkciu tak, aby:
- meno absolventa prišlo ako parameter
- text "úspešne absolvoval" sa skloňoval podľa pohlavia
- áno, znamená to, že aj pohlavie musí prísť ako parameter
const GENDER_MALE = 'male';
const GENDER_FEMALE = 'female';
function generateCertificate(name, gender) {
// ...
let completedText = 'úspešne absolvovala kurz';
if (gender === GENDER_MALE) {
completedText = 'úspešne absolvoval kurz';
}
return `
<svg height="210mm" width="297mm" ... >
<rect ... />
<text ...>Potvrdenie o absolvovaní kurzu</text>
<text ...>${name}</text>
<text ...>${completedText}</text>
<text ...>Základy programovania v JavaScripte</text>
<!-- ... -->
</svg>
`;
}
Riešenie:
Úloha: Vytvorte funkciu generateCertificates, ktorá:
- dostane zoznam absolventov ako argument
- každý študent bude reprezentovaný ako objekt s vlastnosťami name a gender
- funkcia vygeneruje SVG obrázok certifikátu pre každého absolventa
const students = [
{
name: 'Ferko Mrkvička',
gender: GENDER_MALE,
},
{
name: 'Janka Nová',
gender: GENDER_FEMALE,
},
];
function generateCertificates(students) {
let certificatesHtml = '';
for (let i = 0; i < students.length; i += 1) {
certificatesHtml =
certificatesHtml + generateCertificate(students[i].name, students[i].gender);
}
return certificatesHtml;
}
function generateCertificate(name, gender) {
// ...
}
document.querySelector('#app').innerHTML = generateCertificates(students);
Riešenie:
Nie sú certifikáty zvyčajne viac...
fancy,
s farbami,
vlnovkami a tak?
Zložitejšie tvary v SVG
<path
d="
M 200, 150
l 400, 750
l -400, 0
Z
"
fill="red"
stroke="black"
stroke-width="1"
/>
Zložitejšie tvary v SVG
<path
d="
M 500, 400
q 200, -350, 400, 0
Z
"
fill="blue"
stroke="black"
stroke-width="10"
/>
Zložitejšie tvary v SVG
<path
d="
M 500, 400
q 200, -350, 400, 0
Z
"
fill="blue"
stroke="black"
stroke-width="10"
/>
<path
d="
M 1000, 400
q 200, -350, 400, 0
Z
"
fill="none"
stroke="black"
stroke-width="10"
/>
Zložitejšie tvary v SVG
<path
d="
M 500, 400
q 200, -350, 400, 0
Z
"
fill="blue"
stroke="black"
stroke-width="10"
/>
<path
d="
M 1000, 400
q 200, -350, 400, 0
Z
"
fill="none"
stroke="black"
stroke-width="10"
/>
<path
d="
M 1500, 400
q 200, -350, 400, 0
"
fill="none"
stroke="black"
stroke-width="10"
/>
Zložitejšie tvary v SVG
<path
d="
M 1500, 400
q 200, -350, 400, 0
t 400, 0,
400, 0,
400, 0
"
fill="none"
stroke="black"
stroke-width="10"
/>
Urobme si funkciu na generovanie príkazov pre vlnovku
function getRelativeWaveCommand(controlPoint, stepPoint, numOfWaves) {
if (numOfWaves < 1) {
return '';
}
let command = `q ${controlPoint.x}, ${controlPoint.y}, ${stepPoint.x}, ${stepPoint.y}`;
if (numOfWaves > 1) {
command = command + ' t ';
}
for (let i = 0; i < numOfWaves - 1; i += 1) {
command = command + `${stepPoint.x}, ${stepPoint.y} `;
}
return command;
}
Skúsme vygenerovať vlnovku na pozadie
function generateBackground() {
return `
<path
d="
M 0, 2
${getRelativeWaveCommand(
{ x: 4, y -4},
{ x: 6, y: 0},
10
)}
"
fill="none"
stroke="red"
stroke-width="1"
/>
`;
}
function generateCertificate(name, gender) {
// ...
return `
<svg ...>
${generateBackground()}
// ...
</svg>
`;
}
Skúsme vygenerovať vlnovku na pozadie na celú šírku
function generateBackground() {
return `
<path
d="
M 0, 2
${getRelativeWaveCommand(
{ x: 4, y -4},
{ x: 6, y: 0},
2970 / 6
)}
"
fill="none"
stroke="red"
stroke-width="1"
/>
`;
}
function generateCertificate(name, gender) {
// ...
return `
<svg ...>
${generateBackground()}
// ...
</svg>
`;
}
Skúsme ju zopakovať pre celú výšku (opakujme po 6 bodoch)
function generateBackground() {
let paths = '';
for (let i = 0; i < 2100 / 6; i += 1) {
paths += `<path d="M 0,${2 + i * 6} ${getRelativeWaveCommand(
{ x: 4, y: -4 },
{ x: 6, y: 0 },
2970 / 6
)}" fill="none" stroke="red" stroke-width="1" />`;
}
return paths;
}
function generateCertificate(name, gender) {
// ...
return `
<svg ...>
${generateBackground()}
// ...
</svg>
`;
}
Nemajú certifikáty prelínajúce sa vlnovky rôznych farieb?
Pridajme modrú vlnovku kúsok za červenou
function generateBackground() {
let paths = '';
for (let i = 0; i < 2100 / 6; i += 1) {
paths += `<path d="M 0,${2 + i * 6} ${getRelativeWaveCommand(
{ x: 4, y: -4 },
{ x: 6, y: 0 },
2970 / 6
)}" fill="none" stroke="red" stroke-width="1" />`;
paths += `<path d="M 0,${4 + i * 6} ${getRelativeWaveCommand(
{ x: 4, y: 4 },
{ x: 6, y: 0 },
2970 / 6
)}" fill="none" stroke="blue" stroke-width="1" />`;
}
return paths;
}
Nedalo by sa urobiť vlnovkové orámovanie pre štvorec?
function generateWavyRect() {
const wavesOnWidth = (2770 - (15 - 5) * 2) / 30 - 1;
const wavesOnHeight = (1900 - (15 - 5) * 2) / 30 - 1;
const waveOnTop = getRelativeWaveCommand({ x: 15, y: 10 }, { x: 30, y: 0 }, wavesOnWidth);
const waveOnRight = getRelativeWaveCommand({ x: -10, y: 15 }, { x: 0, y: 30 }, wavesOnHeight);
const waveOnBottom = getRelativeWaveCommand({ x: -15, y: -10 }, { x: -30, y: 0 }, wavesOnWidth);
const waveOnLeft = getRelativeWaveCommand({ x: 10, y: -15 }, { x: 0, y: -30 }, wavesOnHeight);
return `
<path d="
M 100,115
a 15,15,0,0,1,15,-15
l 5,0
${waveOnTop}
l 5,0
a 15,15,0,0,1,15,15
l 0,5
${waveOnRight}
l 0,5
a 15,15,0,0,1,-15,15
l -5,0
${waveOnBottom}
l -5,0
a 15,15,0,0,1,-15,-15
l 0,-5
${waveOnLeft}
l 0,-5
Z
" fill="rgba(255, 255, 255, 0.5)" stroke="black" stroke-width="1"
/>
`;
}
Vlnovkové orámovanie pre štvorec:
function generateCertificate(name, gender) {
// ...
return `
<svg ...>
${generateBackground()}
<rect ... />
${generateWavyRect()}
// ...
</svg>
`;
}
Vlnovkové orámovanie pre štvorec:
Certifikáty viete z JavaScriptu poslať aj na tlačiareň
window.print();
A to je všetko
Školenie JS 2020 - záver
By Milan Herda
Školenie JS 2020 - záver
- 309