On Youtube: Javascript syntax
- 00:00 intro
- 00:30 Javascript als scriptingtaal
- 05:00 Javascript uitvoeren
- 08:49 Javascript in een webpagina
- 12:53 console
- 13:17 meerdere scripts linken
- 13:42 interne en inline scripts
- 15:20 variabelen en types
- 17:20 mixen en conversies van types
- 19:22 Infinity, NaN, Undefined
- 21:10 strings, interpolatie, multiline
- 21:57 constanten
- 24:45 const, let of var?
- 25:28 arrays en lijsten
- 27:24 objecten
- 28:52 selecties en iteraties, for-of, forEach
- 31:05 functies
- 32:14 Math, Date, Array...
Werken met Javascript
Javascript als scriptingtaal
Javascript een scripting taal, geen echte programmeertaal zoals C#. Enkele kenmerken:
- In Javascript gebeurt de compilatie tijdens de uitvoering van het script (JIT: just in time compilation), en niet vooraf zoals C# (naar een .exe)
- Je zou verwachten dat het daardoor iets trager is dan bv. C#, maar dankzij JIT kan de code ook nog tijdens uitvoering geoptimaliseerd worden. Gemiddeld is er weinig verschil in snelheid.
- Javascript is (net zoals HTML en CSS) zuiver tekst, en dus is de code moeilijker te beschermen tegen kopiëren dan een C# .exeprogramma.
- Scripting talen hebben vaak een wat speciale, lossere syntax, met minder strakke regels en heel veel vrijheden en verantwoordelijkheden (dat zul je verderop nog wel merken).
- Er zijn veel scripting talen — Python, PHP, Perl, Ruby... — maar er is er maar één die browsers begrijpen: Javascript.
Javascript is syntactisch een erg rijke taal, die zeer compact kan zijn. Kopieer volgende fragment maar eens in een HTML document, en bekijk het resutaat...
<!doctype html>
<html lang="en">
<body>
<canvas id="c"></canvas>
<script>
for(B=i=y=u=b=i=5-5,x=10,I=[],l=[];B++<304;I[B-1]=B%x?B/x%x<2|B%x<2?7:B/x&4?0:l[i++]="ECDFBDCEAAAAAAAAIIIIIIIIMKLNJLKM@G@TSb~?A6J57IKJT576,+-48HLSUmgukgg OJNMLK IDHGFE".charCodeAt(y++)-64:7);function X(c,h,e,s){c^=8;for(var o,S,C,A,R,T,G,d=e&&X(c,0)>1e4,n,N=-1e8,O=20,K=78-h<<9;++O<99;)if((o=I[T=O])&&(G=o^c)<7){A=G--&2?8:4;C=o-9?l[61+G]:49;do if(!(R=I[T+=l[C]])&&!!G|A<3||(R+1^c)>9&&G|A>2){if(!(R-2&7))return K;n=G|(c?T>29:T<91)?o:6^c;S=(R&&l[R&7|32]*2-h-G)+(n-o?110:!G&&(A<2)+1);if(e>h||1<e&e==h&&S>2|d){I[T]=n;I[O]=0;S-=X(c,h+1,e,S-N);if(!(h||e-1|B-O|T-b|S<-1e4))return W(),c&&setTimeout("X(8,0,2),X(8,0,1)",75);I[O]=o;I[T]=R}if(S>N||!h&S==N&&Math.random()<.5)if(N=S,e>1)if(h?s-S<0:(B=O,b=T,0))break}while(!R&G>2||(T=O,(G||A>2|(c?O>78:O<41)&!R)&&++C*--A))}return-K+768<N|d&&N}function W(){i="<table>";for(u=18;u<99;document.body.innerHTML=i+=++u%x-9?"<th width=60 height=60 onclick='I[b="+u+"]>8?W():X(0,0,1)'style='font-size:50px'bgcolor=#"+(u-B?u*.9&1||9:"d")+"0f0e0>&#"+(I[u]?9808+l[67+I[u]]:160):u++&&"<tr>")B=b}W()
</script>
</body>
</html>
- andere voorbeelden van Javascript programma's van minder dan 1000 tekens: Rainbow game, Particles generator
Javascript heeft een lange voorgeschiedenis van naamgeving: oorspronkelijk Mocha gedoopt, dan LiveScript en vervolgens Javascript, om tenslotte hernoemd te worden naar de vandaag officiële naam ECMAScript of kortweg ES. Ook de versienummering is verwarrend: ECMAScript6 of ES6 (a.k.a. Harmony) wordt ook ES2015 genoemd, en komt ES7 dus overeen met ES2016.
Javascript in andere omgevingen
Javascript is enkel een taal, d.w.z. een set van syntaxregels; dit zegt niks over waar het uitgevoerd wordt. In principe kan het uitgevoerd worden in elke omgeving waar een Javascript engine op kan draaien. De meest gekende toepassing is in webpagina’s, maar enkele andere mogelijke omgevingen zijn:
- Windows Scripting Host: shell scripts in Javascript (kan ook op MAC, zie verder)
- NodeJS: server scripts geschreven in Javascript
- Micro:bit: deze populaire microcontroller kan je programmeren met Scratch, Python maar ook met Javascript
- Embedded: plugins voor Adobe Acrobat, Photoshop, Chrome enz... geschreven in Javascript
- ...
In Windows Scripting Host
Je kan Javascript gebruiken om scripts uit te voeren in een Windows command. Codevoorbeeld (en ter vergelijking rechts de C# Console versie):
/* global WScript */
function faculteit(n) {
var resultaat = n;
for (var i = n - 1; i > 1; i--) resultaat *= i;
return resultaat;
}
WScript.StdOut.WriteLine('FACULTEIT BEREKENEN');
WScript.StdOut.WriteLine('');
WScript.StdOut.Write('Geef een geheel getal: ');
var getal = parseInt(WScript.StdIn.ReadLine());
WScript.StdOut.Write('De faculteit is ' + faculteit(getal));
static private int Faculteit(int n) {
int resultaat = n;
for (int i = n - 1; i > 1; i--) resultaat *= i;
return resultaat;
}
static void Main(string[] args) {
Console.WriteLine("FACULTEIT BEREKENEN");
Console.WriteLine();
Console.Write("Geef een geheel getal: ");
int getal = Convert.ToInt32(Console.ReadLine());
Console.WriteLine($"De faculteit is {Faculteit(getal)}");
}
Sla het script op als demoWSH.js, en run het met het cscript commando in een command prompt:
Serverside Javascript met NodeJS
NodeJS is een Javascript runtime omgeving waarmee Javascript buiten de browser kan uitgevoerd worden, bijvoorbeeld om server- of desktop toepassingen te schrijven. Je moet het eerst downloaden en installeren via https://nodejs.org/en Voorbeeldscript voor het opzetten van een eenvoudige server:
const http = require('http');
const port = 8124;
const status = 200;
http.createServer(function(request, response) {
response.writeHead(status, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
}).listen(port);
console.log('Server running at http://127.0.0.1:8124/');
Sla dit script ergens op, bijvoorbeeld als demoNode.js op de desktop. Voer het dan uit met het node commando:
Je kan vervolgens het serveradres openen in de browser:
Javascript in een webpagina
Script extern linken
In de rest van de cursus beperken we ons tot Javascript in web pagina’s. De werkwijze is gelijkend aan hoe je CSS aan een webpagina toevoegt:
- maak een map 'js' in je project
- maak daarin een bestand 'script.js'
- link het onderaan in de <body> (CSS bestanden link je bovenaan in de <head>) je HTML document met <script src="js/scripts.js"></script>
- open de HTML pagina in de browser (bijvoorbeeld met de Go Live knop rechtsonder)
Link je scripts altijd onderaan in de body, zodat alle HTML ingelezen is vóór het script uitgevoerd wordt! Als bonus krijgt de gebruiker dan sneller de inhoud van de pagina te zien, zonder eerst op het inladen van het script te moeten wachten
Voorbeeldcode, HTML en Javascript en het resultaat in de webpagina:
document.getElementById('message').innerHTML = 'Hallo Wereld!';
console.log('einde script');
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World demo</title>
</head>
<body>
<p id="message"></p>
<script src="js/scripts.js"></script>
</body>
</html>
Meerdere scripts linken
Net zoals bij CSS, kan je ook meerdere scripts linken. Een typisch HTML bestand wordt dan:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World demo</title>
<link rel="stylesheet" src="common/vendor/fancybox.min.css">
<link rel="stylesheet" src="common/vendor/owlcarousel.min.css">
<link rel="stylesheet" src="common/vendor/owlcarousel.theme.min.css">
<link rel="stylesheet" src="css/start.css">
<link rel="stylesheet" src="css/styles.css">
</head>
<body>
...
<script src="common/vendor/fancybox.js"></script>
<script src="common/vendor/owlcarousel.js"></script>
<script src="js/library.js"></script>
<script src="js/scripts.js"></script>
</body>
</html>
Interne scriptblokken
In principe kan je scripts ook in de HTML pagina plaatsen, en net zoals bij CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World demo</title>
</head>
<body>
<p id="message"></p>
<script>
document.getElementById('message').innerHTML = 'Hallo Wereld!';
console.log('einde script');
</script>
</body>
</html>
- Interne script blokken getuigen van een slechte stijl. Hou je HTML, CSS en Javascript netjes in aparte bestanden!
Inline scripts
Je kan scripts zelfs inline plaatsen, en net zoals bij CSS:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hello World demo</title>
</head>
<body>
<input type="button" value="I'm a button" onclick="console.log('auch')">
</body>
</html>
Inline scripts zijn NOT DONE. Als je dit tegenkomt op het Internet, neem het dan niet over in een oefening of project!
Console debugger
In de inspector van Chrome (F12 of Shift-Ctrl-I) vind je onder het tabblad "Console" allerlei browser berichten: fouten, waarschuwingen, meldingen... Je kan er ook zelf naar schrijven, wat de Console tot een debugging instrument bij uitstek maakt.
Browsermeldingen
Javascript foutmeldingen komen in de Console terecht, dus hou het altijd goed in de gaten!
document.getElementById('messge').innerHTML = 'Hallo Wereld!'; // FOUT: element messge bestaat niet
console.log('einde script');
Zelf schrijven naar de console
Je kan met console.log()
teksten naar de console schrijven:
const name = 'Rogier';
console.log(`Hello ${name}`);
Je kan het ook gebruiken om variabelen of zelfs hele arrays of objecten te inspecteren:
const names = ['Alice', 'Bob', 'Clive'];
const person = { name: 'rogier', age: '46', isMale: true};
console.log(person);
console.log(names);
Er zijn trouwens nog een hele waslijst andere functies voor console
(volledige lijst zie https://developer.chrome.com/docs/devtools/console/api):
console.table({ name: 'rogier', age: '46', isMale: true});
console.warn('this is a serious warning');
console.error('whoops! an error occured');
debugger
De console werkt asynchroon. Dit is een belangrijk begrip in programmeren in het algemeen, en Javascript in het bijzonder. Het betekent kortweg dat je niet precies weet in welke volgorde instructies uitgevoerd worden (meer hierover later in hoofdstuk 03. asynchrone javascript). Dat heeft in de console onverwachte gevolgen. Neem volgende code:
const person = {
name: 'Rogier',
age: 42
};
console.log(person); // schrijf 'person' naar de console
person.age = 54; // verander achteraf de waarde 'age' naar 54
In de console zie je de waarde '54' staan die pas ingesteld is nádat console.log()
opgeroepen
werd.
De reden is dat waarden in de console niet noodzakelijk verschijnen op het moment in de code waarop
console.log()
opgeroepen wordt. Je kan handmatig het script pauzeren met debugger
, en
dan klopt de waarde wel:
let person = {
name: 'Rogier',
age: 42
};
console.log(person); // schrijf 'person' naar de console
debugger; // pauzeer het script
person.age = 54; // verander achteraf de waarde 'age' naar 54
De weergegeven waarde is nu wel correct:
Variabelen, types & constanten
Variabelen
Variabelen aanmaken is veel eenvoudiger dan in C#: je gebruikt gewoon het gereserveerd woord let
.
Een vergelijking voor de meest voorkomende types:
let num1 = 3; // geheel getal
let num2 = 3.14; // kommagetal
let boo = true; // boolean
let str = 'hello'; // string
let arr = [1, 2, 3, 5, 8, 13]; // array
let dat = new Date(); // Date object
let me = { age: 54, name: 'Rogier' }; // anoniem object
int num1 = 3; // geheel getal
double num2 = 3.14; // kommagetal
bool boo = true; // boolean
string str = "hello"; // string
int[] arr = new int[] { 1, 2, 3, 5, 8, 13 }; // array
DateTime dat = new DateTime(); // DateTime object
var me = new { Age = 54, Name = "Rogier" }; // anoniem object
In veel (oude) Javascript code zul je nog var
zien gebruiken in plaats van let
.
var num1 = 3; // geheel getal
var num2 = 3.14; // kommagetal
...
- de reden is nogal technisch (
var
definieert een variabele globaal,let
lokaal), maar de regel is: gebruik altijdlet
in plaats vanvar
Weak typing van variabelen
Variabelen in Javascript zijn weakly typed, d.w.z. het type kan veranderen als je er een andere waarde aan toewijst:
let num = 3; // num is een getal
num = "Rogier"; // num is nu een string
num = false; // num is nu een boolean
int num = 3; // num is een getal
num = "Rogier"; // FOUT!
num = false; // FOUT!
- hoewel een variabele veranderen van type kan, is het een bron van veel fouten en een slechte programmeerstijl!
Mixen van variabelen
Als je verschillende types variabelen mixt in één expressie, passen zowel Javascript als C# in bepaalde gevallen automatische conversie toe. Javascript is daarin nog een flexibeler dan C#. De verschillen zijn echter groot, zoals uit onderstaande vergelijking blijkt:
console.log(3 + '2'); // 32; 3 omgezet naar string
console.log(3 + "2"); // 32; 3 omgezet naar string
console.log(3 * '2'); // 6; '2' omgezet naar getal
console.log(3 * "2"); // 6; "2" omgezet naar getal
console.log(3 - '2'); // 1; '2' omgezet naar getal
console.log(3 - "2"); // 1; "2" omgezet naar getal
console.log(3 == '3.0'); // true; '3.0' omgezet naar getal
console.log(3 / 2); // 1.5; gewone deling
console.log(3.0 / 2); // 1.5; gewone deling
Console.WriteLine(3 + '2'); // 53; '2' omgezet naar ASCII 50
Console.WriteLine(3 + "2"); // 32; 3 naar string omgezet
Console.WriteLine(3 * '2'); // 150; '2' omgezet naar ASCII 50
Console.WriteLine(3 * "2"); // FOUT!
Console.WriteLine(3 - '2'); // -47; '2' omgezet naar ASCII 50
Console.WriteLine(3 - "2"); // FOUT!
Console.WriteLine(3 == '3.0'); // FOUT!
Console.WriteLine(3 / 2); // 1; gehele deling
Console.WriteLine(3.0 / 2); // 1.5; gewone deling
- moraal van het verhaal: vertrouw nooit op automatische conversie, noch in Javascript noch in C#! De resultaten zijn werkelijk te onvoorspelbaar, en een kweeknest van fouten
Conversie van variabelen
Pas daarom bij het mixen van types in één expressie altijd conversie toe:
const test = 3;
console.log(test + parseInt('2')); // 5
console.log(test.toString() + '2'); // 32
console.log(parseFloat(test) / 2); // 1.5
int test = 3;
Console.WriteLine(test + Convert.ToInt32("2")); // 5
Console.WriteLine(Convert.ToString(test) + '2'); // 32
Console.WriteLine(Convert.ToDouble(test) / 2); // 1.5
- in Javascript gebruik je
parseInt()
,parseFloat()
,toString()
Identity operator
Er is een verschil tussen de identity operator === (vergelijkt waarde én type) en de equals operator == (vergelijkt enkel waarden):
console.log('3' == 3); // true
console.log('3' === 3); // false; verschillende types
console.log('' == false); // true
console.log('' === false); // false; verschillende types
- het is in principe een goede stijl de identity operator te gebruiken waar mogelijk, maar daar gaan we in dit vak niet echt moeilijk over doen
Infinity, NaN, undefined
Javascript heeft drie waarden die C# niet kent: Infinity
(oneindig), NaN
(Not a
Number of “geen getal”) en undefined
(waarde onbekend)
let test1;
console.log(test1); // undefined
console.log(7 * "bladibla"); // NaN
console.log(6 / 0); // Infinity
int test1;
Console.WriteLine(test1); // fout! variabele heeft geen waarde
Console.WriteLine(7 * "bladibla"); // fout! mixen van types
Console.WriteLine(6 / 0); // fout! deling door 0
- net zoals bij automatische conversie: maak hier best geen gebruik van, om fouten te vermijden
Constanten
Een variabele declareer je als constante met const
. Het betekent dat je geen nieuwe waarde mag
toekennen. Bij samengestelde types als objecten, arrays, lijsten enz... kan je wel nog steeds de individuele
elementen of properties aanpassen. Ter illustratie:
const test1 = "abc";
const test2 = 123;
const test3 = [ 12, 9, 4, 33 ];
const test4 = new Date(1970, 6, 23);
test3[1] = 10; // aanpassing één element; ok
test4.setFullYear(1971); // aanpassing één property; ok
test1 = "xyz" // FOUT! variabele overschrijven mag niet
test2 = 456; // FOUT! variabele overschrijven mag niet
test3 = [ 55, 67, 3 ]; // FOUT! variabele overschrijven mag niet
test4 = new Date(1972, 8, 12); // FOUT! variabele overschrijven mag niet
- in C# kunnen samengestelde types als arrays en objecten niet
const
gedeclareerd worden; daar moet jereadonly
gebruiken
const
, let
of var
?
De afspraken zijn:
- gebruik standaard
const
- gebruik
let
als je van plan bent in de loop van het programma een nieuwe waarde toe te wijzen - gebruik nooit
var
Onthoud dus deze regel: const
wanneer mogelijk!
Qua hooflettergebruik voor constanten mag je vrij kiezen tussen UPPERCASE_UNDERSCORE en camelCase notatie. En mogelijke keuze is de eerste notatie enkel voor “echte” constanten als MAX_POGINGEN of CANVAS_WIDTH te gebruiken, en de tweede voor constanten die eigenlijk variabelen zijn die toevallig maar één keer toegewezen worden, zoals familieNaam of boodschappenLijst.
Strings
Drie soorten quotes
In C# moet je dubbele quotes gebruiken voor strings, maar in Javascript kan je ook enkele quotes of backticks gebruiken. Een vergelijking:
let first = 'Rogier'; // enkele quotes
let last = "van der Linde"; // dubbele quotes
let greet1 = 'Zeg "Welkom"'; // enkel en dubbel genest
let greet2 = "Zeg 'Welkom'"; // omgekeerd mag ook
let message = `Welkom ${first} ${last}`; // string interpolatie: gebruik backticks
string first = "Rogier";
string last = "van der Linde";
string greet1 = "Zeg \"Hallo\""; // escape nodig
string greet2 = "Zeg 'Hallo'"; // geen escape nodig
string message = $"Hallo {first} {last}"; // string interpolatie
- in Javascript mag je kiezen welke je gebruikt — al zijn enkele quotes het meest gebruikelijk
- bij string interpolatie moet je backticks gebruiken
String interpolatie, multiline strings
Net zoals C# kent Javascript string interpolatie en multiline strings. In C# worden ze met $ reps. @ aangeduid, in javascript met backticks:
// string interpolatie
let name = 'Rogier';
console.log(`Welkom ${name}`);
// multiline string
console.log(`Een
twee
drie
vier
hoedje van
hoedje van...`);
// string interpolatie
string naam = "Rogier";
Console.WriteLine($"hallo {naam}");
// multiline string
Console.WriteLine(@"Een
twee
drie
vier
hoedje van
hoedje van...");
String methodes en properties
Enkele voorbeelden:
console.log('ha'.repeat(3)); // hahaha
console.log('yes we can'.split(' ')) // ['yes', 'we', 'can']
console.log('hello'.endsWith('hell')); // true
console.log('hello'.includes('ell')); // true
De belangrijkste properties:
property | omschrijving |
---|---|
length |
aantal karakters van de string |
De belangrijkste methodes:
methode | Omschrijving |
---|---|
endsWith(str) |
controleert of een string eindigt met een stuk tekst |
includes(str) |
controleert of een string een stuk tekst bevat |
indexOf(str) |
zoek een waarde en geef eerste index terug (-1 indien niet gevonden) |
lastIndexOf(str) |
zoek een waarde en geef laatste index terug (-1 indien niet gevonden) |
replace(str1, str2) |
vervangt de eerst gevonden str1 door str2 |
replaceAll(str1, str2) |
vervangt alle gevonden str1 door str2 |
split(separator) |
splitst een tekst in een array |
startsWith(str) |
controleert of een string begint met een stuk tekst |
substr(start, num) |
substring beginnende van positie start en num karakters |
substring(start, end) |
substring van posities start tot end |
toLowerCase() |
zet om naar kleine letters |
toUpperCase() |
zet om naar hoofdletters |
trim() |
verwijder spaties aan begin en einde |
Lijsten & arrays
Arrays
Arrays in Javascript zijn veel losser dan in C#. Je mag types mixen, en onbeperkt elementen toevoegen:
const arr1 = [];
arr1[0] = 'abc';
arr1[1] = 'def';
console.log(arr1.length); // 2
arr1[1] = 12; // getal toevoegen
arr1[2] = false; // boolean toevoegen: ok
arr1[100] = 'test'; // tekst toevoegen: ok
console.log(arr1.length); // 101
string[] arr1 = new string[10];
arr1[0] = "abc";
arr1[1] = "def";
Console.WriteLine(arr1.Length); // 10
arr1[1] = 12; // fout! is geen string
arr1[2] = false; // fout! is geen string
arr1[100] = "test"; // fout! buiten het bereik
- hoewel het kan, is het mixen van types in arrays een bron van veel fouten en een slechte programmeerstijl
Lijsten
In Javascript bestaat geen aparte implementatie voor lijsten, maar array methodes als push()
,
pop()
en includes()
hebben wel veel overeenkomsten met de C# List methodes
Add()
, Remove()
en Contains()
:
const list1 = ['boter', 'kaas', 'melk'];
list1.push('eieren'); // voeg item toe
list1.push('tomaten'); // voeg item toe
if (list1.includes('kaas')) console.log('lijst bevat kaas');
console.log(`lijst bevat ${list1.length} items`); // 5
const first = list1.pop(); // verwijder laatste (tomaten)
const last = list1.shift(); // verwijder eerste (boter)
list1.reverse(); // keer volgorde om
console.log(`lijst: ${list1.join(', ')}`); // eieren, melk, kaas
List<string> list1 = new List<string> { "boter", "kaas", "melk" };
list1.Add("eieren"); // voeg item toe
list1.Add("tomaten"); // voeg item toe
if (list1.Contains("kaas")) Console.WriteLine("lijst bevat kaas");
Console.WriteLine($"lijst bevat ${list1.Count} items"); // 5
list1.Remove("tomaten"); // verwijder laatste
list1.Remove("boter"); // verwijder eerste
list1.Reverse(); // keer volgorde om
Console.WriteLine($"items: ${String.Join(", ", list1)}"); // melk, eieren, kaas
Properties en methodes
Er wordt in Javascript geen onderscheid gemaakt tussen arrays en lijsten.
Properties:
methode | Omschrijving |
---|---|
length |
aantal elementen van de array |
Methodes:
methode | omschrijving |
---|---|
includes() |
controleert of de rij een waarde bevat |
indexOf() |
zoek een waarde en geef eerste index terug (-1 indien niet gevonden) |
join() |
voeg elementen samen tot een string |
pop() |
verwijder en return element achteraan de rij |
push() |
voeg element toe achteraan de rij |
shift() |
verwijder en return element aan het begin de rij |
Extensiemethodes
Net zoals in veel andere programmeertalen, kent Javascript een aantal zgn. extensiemethodes voor arrays. De
interessantste zijn find()
, filter()
en map()
. Een codevoorbeeld:
const arr1 = ['boter', 'kaas', 'melk', 'eieren'];
console.log(arr1.find(str => str.startsWith('k'))); // 'kaas'
console.log(arr1.filter(str => str.length > 4 )); // ['boter', 'eieren']
console.log(arr1.map(str => str.length )); // [5, 4, 4, 6]
const arr2 = [16, -77, 3, 4, -9 ];
console.log(arr2.find(n => n > 0 && n < 10 )); // 3
console.log(arr2.filter(n => n % 2 == 0)); // [16, 4]
console.log(arr2.map(el => el + 1 )); // [17, -76, 4, 5, -8]
- extensiemethodes laten vaak toe heel compacte en leesbare code te schrijven — een aanrader om mee te leren werken!
Objecten
Objecten maken
In Javascript kan je “ad hoc” objecten maken, in C# moet je eerst een klasse maken (zie leerstof OO Application Development):
const myCar = {
make: 'Mercury Bobcat',
speed: 0,
engineOn: true,
constructionDate: new Date(1976, 6, 24),
accelerate: function(acc) {
if (this.engineOn) speed += acc;
}
}
myCar.accelerate(25);
console.log(`current speed is ${myCar.speed}`);
class Car {
public string Make;
public int Speed;
public bool EngineOn;
public DateTime ConstructionDate;
public void Accelerate(int acc) {
if (EngineOn) Speed += acc;
}
}
Car myCar = new Car() {
Make = "Mercury Bobcat",
Speed = 0,
EngineOn = true,
ConstructionDate = new DateTime(1978, 6, 23)
}
myCar.Accelerate(25);
Console.WriteLine($"current speed is {myCar.Speed}");
Properties toevoegen
In Javascript kan je achteraf nog onbeperkt properties toevoegen, in C# kan dat niet:
const myCar = {
make: 'Mercury Bobcat',
speed: 0,
engineOn: false,
constructionDate: new Date(1976, 6, 24),
accelerate: function(acc) => {
if (this.engineOn) speed += acc;
}
}
myCar.color = 'silver'; // ok; nieuwe property toegevoegd
class Car {
public string Make;
public int Speed;
public bool EngineOn;
public DateTime ConstructionDate;
public void Accelerate(int acc) {
if (EngineOn) Speed += acc;
}
}
Car myCar = new Car() {
Make = "Mercury Bobcat",
Speed = 0,
EngineOn = false,
ConstructionDate = new DateTime(1978, 6, 23)
}
myCar.Color = "silver"; // FOUT! property bestaat niet
Objecten als parameter
Objecten worden vaak gebruikt om properties in één variabele te groeperen, die dan makkelijk als parameter kan doorgegeven worden:
// functie met één 'thing' parameter
function getDescription(thing) {
const lines = [];
lines.push(`Name: ${thing.kind}`);
lines.push(`Color: ${thing.color}`);
lines.push(`It weighs ${thing.volume * thing.density}kg`);
return lines.join('\n');
}
// stel het object samen
const stone = {
kind: 'lapis lazuli',
volume: 0.03, // m³
density: 3000, // kg/m³
color: 'darkblue'
}
// geef het door aan de functie
console.log(getDescription(stone));
Anonieme objecten
Net zoals bij anonieme functies, kan je ook ad hoc objecten aanmaken en meegeven zonder ze eerst een naam te geven:
// functie met één 'thing' parameter
function getDescription(thing) {
const lines = [];
lines.push(`Name: ${thing.kind}`);
lines.push(`Color: ${thing.color}`);
lines.push(`It weighs ${thing.volume * thing.density}kg`);
return lines.join('\n');
}
// geef een anoniem object door aan de functie
console.log(getDescription({
kind: 'lapis lazuli',
volume: 0.03, // m³
density: 3000, // kg/m³
color: 'darkblue'
}));
Selecties en iteraties
Selecties
In Javascript komt de syntax van de selecties if
, if
-else
en
switch
-case
overeen met C#. Een if
-else
voorbeeld:
const badGrades = true;
if (badGrades) {
console.log('House arrest for two weeks');
} else {
console.log('No house arrest');
}
bool badGrades = true;
if (badGrades) {
Console.WriteLine("House arrest for two weeks");
} else {
Console.WriteLine("No house arrest");
}
Vergeet ook de handige ternaire operator niet:
const number = 13;
console.log(`${number} is ${number % 2 == 0 ? 'even' : 'odd'}`);
int number = 13;
Console.WriteLine($"{number} is {(number % 2 == 0 ? "even" : "odd")}");
Iteraties
herhalingsstructuren while
, do
-while
, for
In Javascript komt de syntax van de selecties while
, do
-while
en
for
overeen met C#. Een for
voorbeeld:
// definieer een array
const forrestFriends = ['Bubba', 'Lt. Dan'];
// itereer over de waarden
for (let i = 0; i < forrestFriends.length; i++) {
console.log(`friend nr. ${i}: ${forrestFriends[i]}`);
}
// definieer een array
string[] forrestFriends = { "Bubba", "Lt. Dan" };
// itereer over de waarden
for (int i = 0; i < forrestFriends.Length; i++) {
Console.WriteLine($"friend number {i}: {forrestFriends[i]}");
}
itereren over arrays met for
-of
De for
-of
iteratie in Javascript komt overeen met
foreach
-in
in C#:
// definieer een array
const forrestFriends = ['Bubba', 'Lt. Dan'];
// itereer over de waarden
for (const friend of forrestFriends) {
console.log(friend); // Bubba, Lt. Dan
}
// defininieer een array
string[] forrestFriends = { "Bubba", "Lt. Dan" };
// itereer over de waarden
foreach (string friend in forrestFriends) {
Console.WriteLine(friend); // Bubba, Lt. Dan
}
itereren over collecties met forEach
Javascript heeft nog een verkorte notatie (zonder C# equivalent) die velen zeer handig vinden:
// definieer een array
const forrestFriends = ['Bubba', 'Lt. Dan'];
// itereer over de waarden
forrestFriends.forEach(friend => {
console.log(friend); // Bubba, Lt. Dan
});
Itereren over object keys met for
-in
Dit heeft niet direct een C# equivalent. Je kan het gebruiken om te itereren over de keys van een object:
const myCar = {
make: 'Mercury Bobcat',
speed: 0,
engineOn: true,
constructionDate: new Date(1976, 6, 24),
accelerate: function(acc) {
if (this.engineOn) speed += acc;
}
}
for (const key in myCar) {
console.log(`${key} is een ${typeof myCar[key]}`)
}
Functies
Klassieke notatie
Methodes in C# noemt men in Javascript functies. Een vergelijking van de syntax:
function getFibonacciNumbers(n) {
if (n <= 0) return [];
if (n == 1) return [0];
const arrFib = [];
arrFib[0] = 0;
arrFib[1] = 1;
for (let i = 2; i < n; i++) {
arrFib[i] = arrFib[i - 2] + arrFib[i - 1];
}
return arrFib;
}
private static int[] GetFibonacciNumbers(int n) {
if (n <= 0) return new int[0] { };
if (n == 1) return new int[1] { 0 };
int[] arrFib = new int[n];
arrFib[0] = 0;
arrFib[1] = 1;
for (int i = 2; i < n; i++) {
arrFib[i] = arrFib[i - 2] + arrFib[i - 1];
}
return arrFib;
}
Notatie als constante
Je kan in Javascript een methode ook noteren als constante. Volgende notaties zijn gelijkwaardig (of toch bijna, er is een klein verschil, maar dat is voor deze cursus niet zo belangrijk)
const getFibonacciNumbers = function(n) {
...
}
function getFibonacciNumbers(n) {
...
}
Arrow expression notatie
Een verkorte notatie die je in nog andere talen tegenkomt, is de (...) => { ... }
vorm.
Volgende notaties zijn gelijkwaardig:
const getFibonacciNumbers = function(n) {
...
}
const bepaalGgd = function(get1, get2) {
...
}
const getFibonacciNumbers = n => {
...
}
const bepaalGgd = (get1, get2) => {
...
}
- je komt ze vooral veel tegen in extensie methodes, zie aldaar
Optionele parameters
Je kan net zoals in C# standaardwaarden instellen voor parameters. Waar je geen waarden opgeeft, worden standaardwaarden genomen:
function orderDetails(verkoper, product, prijs, klant = null, aantal = 1, kortingPerc = 0) {
return `
Verkoper: ${verkoper}
Klant: ${(klant == null ? '(onbekend)' : klant)}
Verkoop: ${aantal} x ${product}
Korting: ${(kortingPerc == 0 ? 'geen' : kortingPerc + '%')}
Te betalen: ${Math.round(prijs * aantal * (100 - kortingPerc) / 100, 2)} euro`;
}
console.log(orderDetails('Gift shop', 'Red Mug', 12.5));
Functies als parameters
Aangezien je functies als variabelen (of constanten) kan noteren, kan je ze ook als argument meegeven aan functies:
// declareer methode end()
function end() {
console.log('Ok, that was funny 😄');
}
// declareer methode speak(), die als laatste parameter een functie 'callback' accepteert
function speak(quote, callback) {
console.log(quote);
callback(); // voer de tweede parameter uit
}
// roep speak() op met end() als argument
speak('Behind every great man is a woman rolling her eyes.', end);
Anonieme functies
Je kan trouwens ook rechtstreeks een methode meegeven, b.v. met de arrow expression notatie:
// declareer methode speak(), die als laatste parameter een functie 'callback' accepteert
function speak(quote, callback) {
console.log(quote);
callback(); // voer de tweede parameter uit
}
// roep speak() op met een arrow expression functie als laatste argument
speak('Behind every great man is a woman rolling her eyes.', () => {
console.log('Ok, that was funny 😄');
});
- de letterlijke methode heeft geen naam end() meer zoals in het eerste voorbeeld; men noemt dat dan ook een anonieme functie
Ingebouwde klassen: Math, Date, Array, Random...
Minder dan C#, maar Javascript heeft ook een aantal ingebouwde klassen als Math
,
Date
, Array
... De syntax verschilt helaas vaak veel. Een paar typische voorbeelden:
// Date example
const now = new Date();
console.log(now.getFullYear());
// Math example
console.log(Math.ceil(Math.random() * 10));
// Array example
const arr1 = [ 'melk', 'boter', 'eieren' ];
arr1.sort();
console.log(arr1.join(', '));
// Date example
DateTime now = DateTime.Now;
Console.WriteLine(now.Year);
// Math/Random example
Random rnd = new Random();
Console.WriteLine(Math.ceil(rnd.Next() * 10));
// Array example
string[] arr1 = { "melk", "boter", "eieren" }
Array.Sort(arr1);
Console.WriteLine(String.Join(", ", arr1));
- voor een volledig overzicht zie W3Schools of Mozilla.org
Stijlregels
Accolades
Als je code block uit één regel bestaat, mag je in theorie de accolades weglaten. Dit is een slechte stijl, dus schrijf altijd de accolades voluit:
if (age < 6)
console.log('child');
else if (age < 18)
console.log('junior');
else
console.log('adult');
if (age < 6) {
console.log('child');
} else if (age < 18) {
console.log('junior');
} else {
console.log('adult');
}
- het weglaten van accolades lijkt misschien een aantrekkelijk idee, maar het maakt je code foutgevoeliger, minder leesbaar en minder flexibel; je zult echte programmeurs dan ook nooit accolades zien weglaten!
Code commentaar
Voorzie je code rijkelijk van commentaar. Zo blijft het leesbaar voor jou en je collega’s, vandaag en in de toekomst! Inspireer je op volgend voorbeeld:
/*
* Binary sudoku script
*
* @author Rogier van der Linde <rogier.vanderlinde@odisee.be>
*/
// ===========================================
// FUNCTIONS
// ===========================================
/**
* Draws the sudoku board
*
* @param {number} width - board width
* @param {number} height - board height
* @param {array<number>} numbers one dimensional array of numbers
* @returns {string} string representation of the board
*/
function drawBoard(width, height, numbers) {
...
}
....
// ===========================================
// DOM
// ===========================================
// create DOM shorthands
const divLoginModal = document.querySelector('#loginmodal');
const btnLogin = document.querySelector('#btnLogin');
const btnCancel = document.querySelector('#btnCancel');
...
// ===========================================
// EVENTS
// ===========================================
// add event listener
btnLogin.addEventListener('click', function(e) {
e.preventDefault();
divLoginModal.classList.add('show');
});
// ===========================================
// GAME LOGIC
// ===========================================
// initialize board
...
Code layout
Een paar van de belangrijkere regels:
- maximaal één instructie per regel
- spaties voor én na operatoren
- geen spaties voor puntkomma's of binnen haakjes
- geen twee open regels na elkaar
- bovenal: wees consequent
console.log ('Genereer random getal... ' );
let random = Math.Random( ); let g1 =parseInt(random);
console.log(`Het kwadraat is: ${g1*g1}`);
console.log('Genereer random getal... ');
let random = Math.Random();
let g1 = parseInt(random);
console.log(`Het kwadraat is: ${g1 * g1}`);
- VS Code shortcut voor layout: Shift-Alt-F
- als ESLint geen fouten geeft, is het meestal goed (maar controleer op het einde altijd nog eens je layout)
Hoofdlettergebruik
De gewoontes in Javascript qua hoofdlettergebruik en benaming verschillen lichtjes van C#. Een vergelijking:
C# | Javascript | |
---|---|---|
variabelen | camelCase, bv grootsteGetal |
idem |
constanten | PascalCase, bv MaxItems |
UPPERCASE_UNDERSCORE of camelCase, b.v. MAX_ITEMS of maxItems |
methoden (C#) / functies (Javascript) | PascalCase, bv. BerekenGemiddelde() |
camellCase, bv. berekenGemiddelde() |
klassen (C#) / objecten (Javascript) | PascalCase, bv Rectangle |
idem |
Naamgeving
Regels voor naamgeving:
- gebruik betekenisvolle namen, dus geen
g1
,nm
enz... maargetal1
,klantNaam
enz... - methodes beginnen met een werkwoord, bv.
berekenGemiddelde()
,drukMenu()
enz... - boolean variabelen, methodes en properties beginnen met werkwoord als is..., heeft... , bv.
bevatKlinker
,isEven()
,heeftSpelGestart
enz... - kies één taal (Engels óf Nederlands) en gebruik dat in je hele programma, dus niet de ene keer
name
en de andere keerleeftijd
- gebruik de Hongaarse notatie voor HTML elementen, dus prefix altijd met dezelfde drie letters, bv.
btnOk
,lblBericht
,sldPercentage
...
Nesting
Vermijd nesting als het eenvoudig anders kan:
if (age > 6) {
if (age < 18) {
console.log('junior');
} else {
console.log('adult');
}
} else {
console.log('child');
}
if (age < 6) {
console.log('child');
} else if (age < 18) {
console.log('junior');
} else {
console.log('adult');
}
- het weglaten van accolades lijkt misschien een aantrekkelijk idee, maar het maakt je code foutgevoeliger, minder leesbaar en minder flexibel; je zult echte programmeurs dan ook nooit accolades zien weglaten!