Werken met Javascript
Javascript als scriptingtaal
Javascript is een scriptingtaal, 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 resultaat...
<!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:
C:\Users\rogie\Desktop>cscript demoWSH.js Microsoft (R) Windows Script Host Version 5.812 Copyright (C) Microsoft Corporation. All rights reserved. FACULTEIT BEREKENEN Geef een geheel getal: 8 De faculteit is 40320 C:\Users\rogie\Desktop
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:
C:\Users\rogie\Destkop>node demoNode.js Server running at http://127.0.0.1:8124/
Je kan vervolgens het serveradres openen in de browser:
Javascript in een webpagina
Extern script
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>
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>
Intern scriptblok
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.querySelector('#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 script
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!
Javascript console
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.querySelector('#messge').innerHTML = 'Hallo Wereld!'; // FOUT: element met id "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');
Console opmaak
Met de placeholder %c kan je de weergave in de console stijlen. Alles na %c krijgt
de CSS die je als volgende argument meegeeft:
console.log('%c Let op!', 'background: #f00; color: #fff; font-size: 20px; padding: 4px;');
Je kan ook meerdere %c-placeholders in één bericht gebruiken. Elk stuk tekst krijgt dan de CSS
van het volgende argument, zodat je bijvoorbeeld een deel van een zin vet of in kleur kunt zetten:
console.log('Let op dat je %c alleen geziene technieken %c gebruikt.', 'font-weight: bold; color: #0a0;', 'font-weight: normal;');
Zo kan je bijvoorbeeld waarschuwingen of foutmeldingen visueel laten opvallen zonder console.warn()
of console.error() te gebruiken.
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 05. 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 (
vardefinieert een variabele globaal,letlokaal), maar de regel is: gebruik altijdletin 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
constgedeclareerd worden; daar moet jereadonlygebruiken
const, let of var?
De afspraken zijn:
- gebruik standaard
const - gebruik
letals 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
| property/methode | Omschrijving |
|---|---|
length |
aantal karakters van de string |
endsWith(str) |
controleert of een string eindigt met een stuk tekst |
includes(str) |
controleert of een string een stuk tekst bevat |
indexOf(str) |
zoek de positie van een waarde (-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 |
Enkele voorbeelden:
console.log('ha'.repeat(3)); // hahaha
console.log('yes we can'.split(' ')) // ['yes', 'we', 'can']
console.log('hello'.startsWith('hell')); // true
console.log('hello'.includes('ell')); // true
Arrays
Declaratie en gebruik
Vergelijking van arrays in Javascript en C#:
const arr1 = [];
arr1[0] = 'abc';
arr1[1] = 'def';
console.log(arr1.length); // 2
string[] arr1 = new string[10];
arr1[0] = "abc";
arr1[1] = "def";
Console.WriteLine(arr1.Length); // 10
Arrays in Javascript zijn veel losser dan in C#. Je mag types mixen, en elementen toevoegen waar je wil, zonder risico op overflow fouten:
arr1[1] = 12; // getal toevoegen
arr1[2] = false; // boolean toevoegen: ok
arr1[100] = 'test'; // tekst toevoegen: ok
console.log(arr1.length); // 101
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
Properties en methodes
| property/methode | Omschrijving |
|---|---|
length |
aantal elementen van de array |
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 |
Voorbeeldfragment:
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
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
Een object groepeert gerelateerde gegevens als key-value paren. Je kan properties opvragen met punt-notatie of met vierkante haken.
const student = {
voornaam: 'Mia',
achternaam: 'Verhaeghe',
leeftijd: 19
};
console.log(student); // { voornaam: 'Mia', achternaam: 'Verhaeghe', leeftijd: 20 }
console.log(student.voornaam); // 'Mia', dot notatie
console.log(student['achternaam']); // 'Verhaeghe', vierkante haken notatie
student.leeftijd = 20; // property aanpassen
Een key-value paar kan zelfs een functie zijn:
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}`);
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'
}));
Spread operator
De spread operator ... "spreidt" de elementen van een itereerbaar object zoals een array of string.
Voorbeeld voor het samenvoegen van arrays:
const a = [1, 2, 3];
const b = [4, 5, 6];
const samen = [...a, ...b];
console.log(samen); // [1, 2, 3, 4, 5, 6]
Array kopiëren met spread operator:
const origineel = [1, 2, 3];
const kopie = [...origineel];
kopie.push(4);
console.log(origineel); // [1, 2, 3]
console.log(kopie); // [1, 2, 3, 4]
String omzetten naar array van tekens met spread operator:
const woord = 'hallo';
const chars = [...woord];
console.log(chars); // ['h', 'a', 'l', 'l', 'o']
Array als parameters aan een functie meegeven met spread operator:
const getallen = [3, 7, 2, 9];
const max = Math.max(...getallen);
console.log(max); // 9
Zonder spread zou Math.max(getallen) NaN geven, omdat je dan één array doorgeeft
in plaats van vier aparte getallen.
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
});
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...
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.Ceiling(rnd.Next() * 10.0));
// 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
Algemeen
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>
*/
// ===========================================
// DOM
// ===========================================
// create DOM shorthands
const divLoginModal = document.querySelector('#loginmodal');
const lnkLogin = document.querySelector('#lnkLogin');
const btnReset = document.querySelector('#btnReset');
...
// ===========================================
// 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) {
...
}
/**
* Shows login modal
*
* @param {object} e - event sender
*/
function showLogin(e) {
e.preventDefault();
divLoginModal.classList.add('show');
}
....
// ===========================================
// EVENTS
// ===========================================
// add event listeners
btnReset.addEventListener('click', drawBoard);
lnkLogin.addEventListener('click', showLogin);
....
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)
naamgeving
Regels voor naamgeving:
- gebruik betekenisvolle namen, dus geen
g1,nmenz... maargetal1,klantNaamenz... - methodes beginnen met een werkwoord, bv.
berekenGemiddelde(),drukMenu()enz... - boolean variabelen, methodes en properties beginnen met werkwoord als is..., heeft... , bv.
bevatKlinker,isEven(),heeftSpelGestartenz... - kies één taal (Engels óf Nederlands) en gebruik dat in je hele programma, dus niet de ene keer
nameen 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');
}
JavaScript specifiek
hoofdlettergebruik
De gewoontes in Javascript qua hoofdlettergebruik en benaming verschillen lichtjes van C#. Een vergelijking:
| Javascript | C# | |
|---|---|---|
| variabelen | camelCase, bv grootsteGetal |
idem |
| constanten | SCREAMING_SNAKE_CASE of camelCase, b.v. MAX_ITEMS of maxItems |
PascalCase, bv MaxItems |
| methoden (C#) / functies (Javascript) | camelCase, bv. berekenGemiddelde() |
PascalCase, bv. BerekenGemiddelde() |
| klassen (C#) / objecten (Javascript) | PascalCase, bv Rectangle |
idem |
quote gebruik
Voor strings in Javascript zijn er drie mogelijkheden. Houd je aan deze conventie:
- Enkele quotes
'...'— de standaard. Gebruik deze voor gewone strings. - Dubbele quotes
"..."— te vermijden; ze doen hetzelfde als enkele quotes en maken je code inconsistent. - Backticks
`...`— alleen gebruiken wanneer je interpolatie nodig hebt (${variabele}) of een multiline string schrijft.
const naam = 'Rogier'; // standaard: enkele quotes
const groet = `Hallo ${naam}!`; // backticks voor interpolatie
const tekst = `Dit is een lange zin
die over meerdere
regels loopt.`; // backticks voor multiline
const, let of var?
Variabelen declareer je met const, let of var. Houd je aan deze conventie:
const— declareer variabelen standaard metconst, tenzij je de waarde later opnieuw moet toewijzenlet— alleen wanneer je de variabele later opnieuw wil kunnen toewijzenvar— nooit gebruiken; dit is een oude syntax met een aantal problemen (zonder uitleg).
const PI = 3.14; // constant: nooit opnieuw toewijzen
const naam = 'Rogier'; // maak constant als deze waarde later niet meer verandert
const items = []; items.push(1); // constant: elementen toevoegen of verwijderen is geen nieuwe toewijzing
let teller = 0; teller++; // moet let zijn: waarde wordt opnieuw toegewezen
let antwoord; antwoord = 'nee'; // moet let zijn: waarde wordt later toegewezen
strict equality (=== en !==)
Gebruik bij voorkeur === en !==, nooit == of !=. Die laatste doen automatische typeconversie, wat tot onverwachte bugs leidt:
console.log(3 == '3'); // true — string wordt omgezet naar getal
console.log(3 === '3'); // false — verschillende types
console.log(0 == false); // true — beide "falsy"
console.log(0 === false); // false
puntkomma's
Schrijf altijd een puntkomma aan het einde van elke statement:
const naam = 'Rogier'
console.log(naam)
const naam = 'Rogier';
console.log(naam);
geen magic numbers
Definieer constanten voor getallen die een betekenis hebben. Zo blijft de code leesbaar en makkelijker aan te passen:
if (items.length >= 10) { ... }
for (let i = 0; i < 7; i++) { ... }
const MAX_ITEMS = 10;
const DAGEN_PER_WEEK = 7;
if (items.length >= MAX_ITEMS) { ... }
for (let i = 0; i < DAGEN_PER_WEEK; i++) { ... }