n00b pro

01. Javascript Syntax

Dit hoofdstuk is onderdeel van de cursus Javascript. Andere cursussen in dezelfde reeks: HTML, CSS, C#, Ontwikkelomgeving.

On Youtube: Javascript syntax

https://www.youtube.com/embed/Rxn-qPPa5TI

Werken met Javascript

Javascript als scriptingtaal

Javascript een scripting taal, geen echte programmeertaal zoals C#. Enkele kenmerken:

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>

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:

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
resultaat in de 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:

C:\Users\rogie\Destkop>node demoNode.js
Server running at http://127.0.0.1:8124/
run het script in de command prompt

Je kan vervolgens het serveradres openen in de browser:

array

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:

  1. maak een map 'js' in je project
  2. maak daarin een bestand 'script.js'
  3. link het onderaan in de <body> (CSS bestanden link je bovenaan in de <head>) je HTML document met <script src="js/scripts.js"></script>
  4. 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>

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
...

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!

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

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

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

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

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

const, let of var?

De afspraken zijn:

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

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

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]

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]}`)
}
make is een string
speed is een number
engineOn is een boolean
constructionDate is een object
accelerate is een function
resultaat in de console

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) => {
      ...
}

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 😄');
});

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));

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');
}

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:

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}`);

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:

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');
}


pyramid of doom
vermijd de pyramid of doom!