Marko Draisma
Open het bestand 'item.html'. Maak hierin een JavaScript blok met code (in de
) en maak daarin:
a) Een variabele waar wij straks een product object gaan plaatsen
b) Een variabele waar wij straks een datum in gaan zetten (de login tijd van de gebruiker)
Open het bestand 'producten.html'. Maak hierin een JavaScript blok met code (in de ) en maak daarin:
c) Een variabele waar wij straks een reeks (array) in gaan zetten met product prijzen
var invoer1 = 10
var invoer2 = 20
if (invoer1 == invoer2)
{
alert("Invoer gelijk!"); // window.alert() mag ook
}
var invoer1 = 10
var invoer2 = 20
if (invoer1 == invoer2)
{
alert("Invoer gelijk!"); // window.alert() mag ook
}
else
{
alert("Invoer verschillend!")
}
De opdracht(en) na de controle van een if statement moeten we altijd tussen accolades {} opnemen wanneer het om meerdere opdrachten op verschillende regels gaat.
Betreft het één opdracht dan kunnen de accolades achterwege blijven.
Het correcte antwoord is: Juist
Accolades MOETEN we binnen een if statement alleen toevoegen wanneer MEERDERE statements na controle van de conditie moeten worden uitgevoerd op verschillende regels.
Anders gaat de browser er vanuit dat alleen de eerste opdracht bij het if statement behoort en niet de tweede en (eventueel) volgende statements. Bij het opnemen van
een enkel statement is het niet verplicht. Onderstaande DRIE syntaxen zijn dus goed:
if (contole)
statement; statement
if (controle)
statement
if (contole)
{statement;
statement}
De opdracht(en) na de controle van een if statement moeten we altijd tussen accolades {} opnemen. Anders geeft de browser een foutmelding bij het openen van de pagina.
Het correcte antwoord is: Onjuist
Accolades MOETEN we binnen een if statement alleen toevoegen wanneer MEERDERE statements na controle van de conditie moeten worden uitgevoerd, anders gaat de browser er
vanuit dat alleen de eerste opdracht bij het if statement behoort en niet de tweede en (eventueel) volgende statements. Bij het opnemen van een enkel statement zijn
accolades niet nodig. Onderstaande syntaxen zijn dus beide goed:
if (controle)
{statement; statement}
if (controle)
statement
Het switch statement, ook wel case statement genoemd, is een soort if statement met meerdere alternatieven.
var geslacht = prompt("Bent u een man of een vrouw? (M/V)");
switch(geslacht.toUpperCase()){
case "M": console.log("Dag meneer");
break;
case "V": console.log("Dag mevrouw");
break;
default: console.log("Dag persoon");
}
Welke opdrachten van de onderstaande code worden uitgevoerd?
var t = 'x';
switch(t){
case 'y' : document.write(a);
case 'x' : document.write(b);
case 'w' : document.write(c);}
Het correcte antwoord is: document.write(b); en document.write(c); Opdrachten document.write(b); endocument.write(c); worden uitgevoerd, er staat namelijk
GEEN break statement onder statement opdracht2
Code in een loop wordt herhaald uitgevoerd aan de hand van één of meer voorwaarden. Er bestaan meerdere soorten loops die we allemaal gaan bespreken;
while loop
do while loop
for-loop
for-in (wordt afgeraden bij gebruik ES6, liever for-of)
for-of loop
Naast while loops kunnen we ook gebruik maken van for-loops.
For, for in en for of loops
Naast while loops kunnen we ook gebruik maken van for-loops. Lees hiervoor pagina 114 (bovenaan de pagina) óf bekijk de volgende opname over for-loops van Quentin Watt:
In onderstaand voorbeeld staat de traditionele for loop. Achter het keyword for staan drie onderdelen tussen haakjes:
een startwaarde, de voorwaarde om de loop te herhalen, en een statement om de voorwaarde uiteindelijk op false uit te laten komen.
Zonder dat laatste statement zou een oneindige loop kunnen ontstaan.
var klassen = ["Warrior","Mage","Druid","Priest","Hunter","Bard"];
// for-loop:
for (var index=0; index 10){
// Onderstaande code wordt nu NIET uitgevoerd,
// immers: de i>10 conditie is false.
console.log(i + " * " + x + " = " + (i * x));
i++;
}
console.groupEnd();
// tafel van 3 met do while lus
console.group("tafel van 3 met do while loop");
var x = 3;
var i = 1;
do {
// Onderstaande code wordt nu WEL (1x) uitgevoerd,
// immers: de i>10 conditie wordt pas na het codeblok gesteld.
console.log(i + " * " + x + " = " + (i * x));
i++;
} while (i > 10)
console.groupEnd();
Om vroegtijdig uit een loop te kunnen 'springen' kunnen we het commando 'break' gebruiken. Daarnaast bestaat de mogelijkheid al (bijvoorbeeld aan het begin van de code)
in de loop aan te geven dat we met de volgende iteratie (herhaling) verder te gaan.
We kunnen ook aan de for lus meerdere voorwaarden (en ook initialisatiewaarden en ophogingen) meegeven, gescheiden door een komma. Voorbeeld:
for ( teller=1, getal=8 ; teller<=10, getal>0; teller++, getal=teller-2 )
Er zijn hier twee initialisatiewaarden, twee voorwaarde en twee ophogingen.
Hoe vaak wordt de waarde van t in het document geschreven?
0 keer : Aangezien de voorwaarde van de loop niet waar is, zal t nooit naar het scherm geschreven worden.
Een functie is een blok code met accolades er omheen en een naam, zodat we later kunnen terug verwijzen naar dat blok. Een voordeel van het plaatsen van code in een functie,
is dat de code niet direct uitgevoerd wordt, maar pas zodra de functie bij naam wordt aangeroepen. Daarnaast zit er geen limiet aan het aantal keer dat een functie aangeroepen
kan worden.
function eenvoudig()
{
console.log("Dit is een eenvoudige functie");
}
function returnWaarde()
{
var a = 10;
var b = 2;
return a*b;
}
function parameterWaarde(invoer1,invoer2)
{
console.log(invoer1*invoer2);
}
// Aanroep eerste eenvoudige functie:
eenvoudig();
// Aanroep tweede functie, die waarde teruggeeft:
var uitkomst = returnWaarde();
console.log("Resultaat:" + uitkomst);
// Aanroep derde functie, die waarde mee krijgt:
parameterWaarde(20,3);
console.clear();
console.group("vier functies");
var add = function(a, b){
return a + b;
};
console.log(add(3,4));
var subtract = function(a, b){
return a - b;
};
console.log(subtract(3,4));
var multiply = function(a, b){
return a * b;
};
console.log(multiply(3,4));
var divide = function(a, b){
if(b === 0) {
throw "Delen door nul is niet toegestaan"; // het zogeheten opgooien van een fout
// dit hoeven wij nog niet te kennen
}
else
return a / b;
};
console.log(divide(3,4));
// Onderstaande 'try' en 'catch' blokken hoeft u nog niet te kennen
try {
console.log(divide(3,0));
}
catch(error){
console.log(error);
}
console.groupEnd();
console.group("voornaam en achternaam");
function concat(a, b){
if( typeof a == "string" && typeof b == "string" )
return a + " " + b;
}
var voornaam = prompt("wat is uw voornaam? ");
var achternaam = prompt("wat is uw achternaam? ");
console.log("Welkom " + concat(voornaam, achternaam));
console.groupEnd();
Tegenwoordig wordt ook vaak een alternatief gebruikt: de "rest parameter".
Deze laatste parameter krijgt drie puntjes voor de naam, en vangt de waarden op die na de voorgedefinieerde parameters komen.
Bijvoorbeeld:
function telop(eerste, tweede, ...overige){
var resultaat = eerste + tweede;
for(let getal of overige){
resultaat+=getal;
}
return resultaat;
}
console.log(telop(2,3)); // 5
console.log(telop(2,3,4)); // 9
console.log(telop(2,3,4,5)); // 14
Een functie wordt vaak uitgevoerd bij de uitvoering van een zogeheten 'event'. Events gaan af (triggeren) op bijvoorbeeld het moment dat:
de gebruiker op een knop klikt
de pagina geladen is
een invoerveld de focus heeft gekregen
wanneer we de huidige pagina willen verlaten
enzovoorts. Meer hierover in een later hoofdstuk
Een veel gebruikte toepassing van de uitvoering van een functie is na het 'onload' event. Dit event gaat af zodra de pagina (het 'window' object) klaar is met laden.
Vaak wil je met behulp van een JavaScript functie iets aanpassen op je pagina. Uiteraard kan dergelijke code pas goed werken als de pagina klaar is met laden
(en alle benodigde elementen zichtbaar en bruikbaar zijn).
In het volgende voorbeeld gebruikten wij dit 'onload' event om met een functie de achtergrondkleur groen te maken:
console.group("Anonieme functies");
window.onload=function(){
document.body.style.backgroundColor="green";
}
console.groupEnd();
Gegeven is de volgende beweringen:
Een functie eindigt altijd met een return statement;
Onjuist : Het toevoegen van een return statement aan een functie is optioneel.
Gegeven is de volgende bewering:
Aan een functie moeten we altijd een parameter toevoegen.
Is deze bewering juist of onjuist?
Onjuist : In een functie kunnen we een parameter opnemen, als we van buiten de functie een waarde aan de functie willen meegeven. Dit is echter niet verplicht.
function telop(a, b){
if(typeof a !== 'number' || typeof b!== 'number'){
throw 'foute invoer, gebruik getallen';
}
return a + b;
}
console.log(telop('test', 4));
function telop(a, b){
if(typeof a !== 'number' || typeof b!== 'number'){
throw 'foute invoer, gebruik getallen';
}
return a + b;
}
try { // iets wat mis kan gaan:
console.log(3,4); // gaat goed
console.log(telop('test', 4)); // gaat mis: spring naar catch block
console.log(5,6); // wordt niet meer uitgevoerd
}
catch (fout){ // als er iets mis gaat:
console.log("Er ging iets mis: " + fout);
}
function minMax(a,b){
let minWaarde = ab ? a : b;
return {
min: minWaarde,
max: maxWaarde
};
}
let test = minMax(3,4);
console.log(test.min); // 3
console.log(test.max); // 4
console.group("Anonieme functies");
window.onload=function(){
document.body.style.backgroundColor="green";
}
console.groupEnd();
Closures
Een functie kan een andere functie retourneren. Deze geretourneerde functie blijft dan toegang houden tot de "context" waarin deze functie is aangemaakt. Zie ook MDN over closures.
In het volgende voorbeeld wordt een functie aangemaakt die toegang houdt tot een teller. Elke keer als de geretourneerde functie wordt aangeroepen, wordt de teller verhoogd.
function counter(startWith, step){
var result;
return function(){
result= result==undefined? // bestaat result nog niet?
startWith: // begin dan met startwaarde
(result+step); // hoog anders op met step
return result;
};
}
var teller = counter(0,2); // teller is een functie
// die bij elke aanroep de
// variabele result kan lezen
console.log(teller()); // 0
console.log(teller()); // 2
console.log(teller()); // 4)
Wat gebeurt hier precies?
De buitenste functie heeft een variabele result, en twee parameters: startWith en step.
Deze variabele en parameters vormen de context van de binnenste functie.
De binnenste functie wordt geretourneerd. In dit geval wordt deze functie toegekend aan de variabele teller.
Met andere woorden: teller is nu een functie, die toegang houdt tot de variabele result, en tot de parameters startWith en step, die hier gevuld zijn met de waarden 0 en 2.
Vanaf het moment dat teller() wordt aangeroepen wordt result aangepast: als result nog undefined is krijgt deze de waarde van startWith, anders wordt result opgehoogd met step.
Er volgt nu een nog voorbeeld die gebruik maakt van een closure:
var BankRekening = function(nr, sal) {
var nummer = nr;
var saldo = sal;
return {
getSaldo: function() {
return saldo; // geen this, want we zitten in een object.
},
getNummer: function(){
return nummer; // geen this, want we zitten in een object.
}
}
}
// de functie achter 'var BankRekening =' levert dus een object op met twee eigenschappen.
var mijnRekening = new BankRekening(1234,100);
console.log(mijnRekening.getSaldo());
Met een closure kun je juist specifieke code onzichtbaar maken voor de 'buiten wereld'. Wél is het vervolgens mogelijk met get en set methoden de toegankelijkheid naar de lokale variabelen te regelen.
Een IIFE (spreek uit: iffy: Immediately Invoked Function Expression) is een anonieme functie die meteen wordt aangeroepen, zodat in het vervolg alleen nog met het resultaat van die anonieme functie kan worden gewerkt.
Dit wordt onder meer gebruikt om de "global scope" schoon te houden: variabelen, functies, objecten en dergelijke die niet deel uitmaken van een functie, worden automatisch aan het window-object toegekend. Het is good practice om op dat niveau zo weinig mogelijk aan te maken.
Een IIFE is vaak ook een closure. Het volgende voorbeeld hebben we eerder behandeld. In dit voorbeeld wordt de context van de geretourneerde functie echter gevormd door een IIFE.
var teller = (function (startWith, step){
var started = false;
return function(){
if(started) return startWith+=step;
started=true;
return startWith;
};
})(1,2); // de anonieme functie wordt meteen aangeroepen,
// in dit geval met startWith=1 en step=2
// nu bestaat alleen de functie teller in global scope
console.log(teller()); // 1
console.log(teller()); // 3
console.log(teller()); // 5
In het volgende voorbeeld maken we een IIFE aan die een object terug geeft. Hiervoor gelden dezelfde regels; lokalen variabelen in de IIFY functie zijn alleen bekend in de geneste functie of het geneste object.
mijnApp = function(){
var naam;
var leeftijd;
return {
setNaam: function(n){
naam = n; // this.naam?
},
getNaam: function(){
return naam;
},
setLeeftijd: function(l){
leeftijd = l;
},
getLeeftijd: function(){
return leeftijd;
}
}
}();
window.onload=function(){
console.log(mijnApp.getNaam());
mijnApp.setNaam("Gamer");
mijnApp.setLeeftijd("34");
console.log(mijnApp.getNaam());
console.log(mijnApp.getLeeftijd());
}
new Date() zorgt ervoor dat een datumobject wordt aangemaakt. De waarde van het object is de huidige datum. Met methoden als getMonth, getMinutes en getSeconds kan de waarde worden uitgelezen. Met methoden als setMonth, setDay en setSeconds kunnen we de objectwaarde aanpassen.
In objecten zijn eigenschappen en functies voor een bepaald onderdeel (zichtbaar of achter de schermen in JavaScript) van de webpagina samengevoegd. De eigenschappen zeggen iets over het object en met de functies (=methoden) kunnen we het object iets uit laten voeren.
Wat is het resultaat in de browser wanneer de volgende JavaScript-code wordt uitgevoerd:
Bij elk karakter van een tekst hoort een indexnummer, te beginnen bij indexnummer 0.
Op de getoonde tekst worden twee methoden toegepast. De eerste methode na het String object tekst zal ook als eerste worden uitgevoerd.
tekst.substring(7,15) heeft als resultaat het 8e t/m het 16e karakter: "hoofdstuk".
Vervolgens haalt methode charAt(4) het 5e karakter op uit de nieuwe string . Het resultaat is dus "d".
Bij het doorlopen van een Array met een normale for-loop, geven we zelf als eindwaarde van onze teller de 'lengte' van onze Array op. Bekijk hierover volgende voorbeeld:
var klassen = ["Warrior","Mage","Druid","Priest","Hunter","Bard"];
// for-loop:
for (var index=0; index element met alle genestte