Table of Contents

Wat basisdingen

Open een nieuwe browser-pagina en open de console. In Safari moet je daarvoor eerst het Ontwikkel-menu aanzetten. cmd-option-j => chrome, cmd-option-c => safari, cmd-option-k => firefox, kan ook uiteraard via de menu's.

JavaScript is een interactieve taal. Dat betekent dat je het vragen kunt stellen en dat het je antwoorden geeft. De vragen die je stelt heten expressies, en de antwoorden zijn waarden. Als ik 46 nu als expressie ingeef, is het antwoord heel voorspelbaar 46, want de waarde is 46.

> 46
46

Dit was natuurlijk geen erg interessante vraag, we kunnen het veel interessantere vragen stellen, bijvoorbeeld hoeveel is 3 + 5:

> 3 + 5
8

Wat als we vragen wat de waarde van hallo is?

> hallo
ReferenceError: hallo is not defined

Dat betekent dat hallo geen waarde heeft, omdat er geen waarde voor hallo gedefinieerd is. We kunnen het ook andere vragen stellen, zoals:

> Math.sqrt(16)
4

Het verschil tussen 3 + 5 en Math.sqrt(16) is dat Math.sqrt(16) een functie-aanroep is, en de eerste een zogeheten operand, een bewerking. Er zijn in principe 4 bewerkingen: +, -, * en / (er zijn er stiekem nog een paar meer, maar die komen wel als dat nodig is). Een functie-aanroep ziet er altijd uit als naam(argument, argument). Het kan een of meerdere argumenten hebben.

Maar wat is nu de waarde van Math.sqrt? Dat kunnen we zien:

> Math.sqrt
function sqrt() { }

Wat is dit? We weten dat als we het een expressie geven we de waarde van die expressie terugkrijgen, dus dit is de waarde van Math.sqrt, en die waarde is een functie. De console zal dus bij het evalueren de naam van de functie evalueren, daar de waarde van terugkrijgen en die uitvoeren. Bij het evalueren van een functie zal de console bovendien eerst de waarde bepalen van de argumenten, dan de waarde bepalen van de functie, en deze vervolgens aanroepen met de waardes van de argumenten. Bijvoorbeeld:

> 3 + 5 * 8
43

Waarom is het antwoord niet 64? 3 + 5 = 8 en 8 * 8 is 64, toch? Dit komt omdat de "Meneer Van Dalen Wacht Op Antwoord"-regel (Machtsverheffen, Vermenigvuldigen, Delen, Worteltrekken, Optellen, Aftrekken) wordt toegepast: er is een vaste volgorde waarmee bewerkingen worden uitgevoerd. De vermenigvuldiging komt dus eerst, de optelling daarna. Wat moet ik doen om wel 64 als antwoord te krijgen? Door duidelijk aan te geven dat de volgorde anders moet, en dat doe je door er haakjes omheen te zetten:

> (3 + 5) * 8
64

Waarden kunnen verschillende soorten gegevens zijn. We hebben al twee soorten waarden gezien: getallen en functies. In JavaScript hebben getallen het type Number, en functies zijn van het type Function.

Als we nu tekst zouden willen ingeven, kunnen we natuurlijk geen nummer gebruiken. Tekst is geen nummer, dus daar is een apart type voor, en aangezien de computer dom is, moeten we dat expliciet aangeven:

> "Dit is een stuk tekst."
"Dit is een stuk tekst."

De waarde hiervan is dus "Dit is een stuk tekst.", en het type heet String. Strings hebben eigenschappen, en de waarde van die eigenschappen kun je bevragen door achter de expressie een punt te zetten met daarna de naam van de eigenschap:

> "Dit is een stuk tekst.".length
22

Dit kan niet (rechtstreeks) met nummers, omdat de punt een andere betekenis heeft in een getal.

Je zult merken dat zodra je de punt intiept, de console een lijst laat zien. (in FF alles, in Chrome moet je scrollen) Dit zijn alle bestaande eigenschappen van de string. De meeste van de eigenschappen gaan we (nog) niet gebruiken, maar dit is handig als je even was vergeten hoe het ook alweer heette (gebeurt mij ook nog :=) ). We gaan straks meer zien van deze eigenschappen.

De reden dat er verschillende types zijn, is dat die types in een computer uiteindelijk weggeschreven worden in bits / bytes, en dat er een label aan moet hangen zodat de computer weet hoe de gegevens geinterpreteerd moeten worden: "286" is niet hetzelfde 286. Als je de computer de string "286" laat lezen als een getal, komt daar 3.291.190 uit! Bovendien zijn er voor de verschillende types verschillende bewerkingen. Probeer je eens voor te stellen hoe je twee strings zou moeten vermenigvuldigen:

> "test" * "test2" 
NaN

NaN is een speciale waarde die Not A Number vertegenwoordigd. Als je dit tegenkomt heb je ergens een type-fout gemaakt bij een berekening. NaN is bovendien toxic, wat zoveel betekent dat elke bewerking met NaN altijd weer NaN als uitkomst heeft. (Niet zo belangrijk, komt later wel).

We hebben nu de belangrijkste basis-types gezien. Naast deze types zijn er ook types die op een zogeheten hoger niveau zich afspelen. Ik kan bijvoorbeeld wel mijn naam als een string weergeven "Sint Nicolaas", maar als ik nu twee mensen wil hebben? Die kun je wel achter elkaar in een string zetten: "Sint Nicolaas Klus Piet", maar dat is erg onhandig, want het zijn twee personen. Je wil dus iets hebben waarmee ik bijvoorbeeld de namen van meerdere mensen kan hebben waarbij elke naam toch een aparte string is. Zoiets heet een lijst in het Nederlands. [ "Sint Nicolaas", "Klus Piet" ] In JavaScript heet dat een Array, (denk aan het NL woordje "rij"). De verschillende elementen in een Array worden van elkaar gescheiden door middel van een komma. Je kunt in een Array verschillende types tegelijkertijd plaatsen: ["Dit is een zin", 8]. Net zoals String eigenschappen heeft, heeft Array dat ook:

> ["Dit is een zin", 8].length
2

Variabelen

Tot nu toe hebben we steeds alles direct ingegeven. We hebben gebruik gemaakt van zogeheten literals. Dat kan prima voor kleine dingen, maar als het iets complexer wordt, is het erg fijn als je een waarde (tijdelijk) ergens in op kan slaan. Zo'n (tijdelijke) opslagplaats heet een variabele en je maakt er een door let naam = waarde. Een variabele heet zo omdat het een naam is waarvan de waarde kan veranderen zonder dat de naam ook verandert. Bijvoorbeeld:

> var naam = "Sint Nicolaas"; 
undefined
> naam;
"Sint Nicolaas"
> naam = "Klus Piet";
undefined
> naam;
"Klus Piet"

Een variabele in JavaScript kan elk type krijgen en je hoeft dat niet van te voren op te geven. Op het moment van evaluatie wordt dat door de computer zelf bekeken. Het aanmaken van een variabele heet het definiëren van de variabele.

Nu vraag je je wellicht af waarom er undefined als waarde gegeven wordt bij het definiëren van de variabele naam. Dit heeft er mee te maken dat in JavaScript bepaald is dat standaard undefined wordt teruggegeven, tenzij er een waarde is. Aangezien de waarde toegewezen wordt aan een variabele is, wordt deze niet teruggegeven aan de console.

Misschien is het je niet opgevallen, maar in dit laatste voorbeeld zie je dat er ineens punt-komma's aan het eind van de regel staan. Hoewel het niet echt vereist is om regels af te sluiten met punt-komma's is het de gewoonte dit wel te doen, behalve voor dit soort kleine zaken.

Functies als eigenschap

Nu we de belangrijkste types gezien hebben, moeten we even gaan kijken naar de bewerkingen. We hebben bij de nummers al gezien dat je daar de bekende bewerkingen op kunt toepassen. Wat je ook hebt gezien bij String is dat je eigenschappen kunt opvragen door een punt achter de expressie te zetten met daarachter de naam van de eigenschap. In JavaScript kunnen eigenschappen ook functies zijn. Dit wordt bij strings en arrays gebruikt om bewerkingen op de desbetreffende string of array toe te passen. Deze bewerkingen zijn (op een enkele na) non-destructief, wat wil zeggen dat de originele waarde bewaard blijft en de evaluatie een nieuwe waarde oplevert:

> var t = [1,2,3];
undefined
> t.reverse();
[3,2,1]
> t
[1,2,3]

Bij een Array wordt de lijst met eigenschappen alleen maar getoond als de Array-waarde in een variabele zit. Als je het nog niet gedaan hebt, probeer maar eens met t. nadat je de variabele t gedefinieerd hebt. Je kunt de bewerkingen (die functies zijn) vaak herkennen aan het feit dat ze een werkwoordsvorm zijn.

Nu heb je aan lijsten niet zoveel als je er niet elementen uit kunt nemen, of naar specifieke elementen in de lijst kunt wijzen, zoals bijvoorbeeld de tweede naam in de lijst. Dat doe je met behulp van de zogeheten subscript-notatie:

> t[1];
2

Waarom is de waarde die we terugkrijgen 2, en niet 1? Dit komt omdat in JavaScript (en vele andere programmeertalen) men begint te tellen op 0. In het kort is de reden dat de index een offset is. De plaats waar je nu bent is 0 en de plaats waar je bent na 1 stap is 1 stap verder. Het vertelt dus hoeveel stappen er gezet zijn in de lijst. Het is belangrijk dit in de gaten te houden, aangezien een vergissing snel gemaakt is. Deze vergissing komt bovendien zo vaak voor dat hij een naam heeft: een "off-by-one error".

Hoe om te gaan met fouten

Het zal je regelmatig een keer gebeuren dat je een fout maakt. Het kan een typefout zijn, of iets anders dat je over het hoofd hebt gezien. Dit is heel normaal en gebeurt ook de slimste programmeur elke dag wel een keer.

Fouten vallen in principe in twee hoofdcategoriën, namelijk functionele fouten en syntax-fouten.

De simpelste soort fout is een syntax-fout: een fout in de "grammatica" van de programmeertaal. De console zal in dat geval melden dat hij het niet begrijpt:

> var fout = ;
Uncaught SyntaxError: Unexpected token ;

en ook waarom hij het niet begrijpt. Deze mededeling betekent dat hij een punt-komma tegenkomt waar hij het niet verwacht. Dit is ook logisch omdat we in dit geval een waarde willen toekennen aan de variabele fout, maar vergeten zijn de waarde op te geven. Een syntaxfout levert altijd een SyntaxError op.

Complexere fouten zijn functionele fouten: fouten waarbij de code in principe wel iets doet, maar dat je of een verkeerd antwoord krijgt, of een error. Eerst een fout met een error:

> Mat.sqrt();
Uncaught ReferenceError: Mat is not defined

Omdat we een typefout hebben gemaakt (Mat in plaats van Math), meldt de console ons dat Mat niet gedefinieerd is. Deze fout hebben we hierboven al gezien, maar is hier herhaald zodat je 'm nog een keer gezien hebt.

> Math.sqt();
Uncaught TypeError: Math.sqt is not a function
> Math.SQRT();
Uncaught TypeError: Math.SQRT is not a function

Nog twee soorten tiepfouten met een ander resultaat. In beide gevallen meldt de console dat hij een functie-aanroep tegenkomt, maar dat de genoemde eigenschap niet de waarde heeft van een Function. Dit betekent dat de eigenschap niet bestaat / niet gedefinieerd is, of dat hij wel gedefinieerd is, maar een waarde heeft anders dan Function. In het eerste geval zijn we een letter vergeten, maar dat zijn we niet in het tweede geval. Wat is daar niet in orde? We hebben hoofdletters gebruikt en dat maakt een verschil. Deze programmeertaal is zoals dat heet hoofdlettergevoelig.

De laatste soort fout hebben we ook al gezien, maar ook die herhalen we een keer:

> 3 + 5 * 8
43

Dit is een geldige expressie, maar toch komt er iets anders uit dan je zou kunnen verwachten. Dit soort fouten zijn het lastigste omdat je steeds opnieuw al je aannames moet controleren. Als je code schrijft doe je steeds aannames over hoe het zal werken, en daar kun je je nu eenmaal in vergissen. Dus als je niet begrijpt waarom iets niet werkt, probeer te localiseren waar het precies fout gaat door via de console vragen te stellen.

Wat in ieder geval heel belangrijk is, dat je geduld met jezelf hebt en accepteert dat je alleen kunt leren door fouten te maken en te proberen te begrijpen waarom je die fout gemaakt hebt.

Je hebt nu de belangrijkste basics van JavaScript gezien. Nu kunnen we ermee aan de slag met muziek.