Les 3 — Variabelen

Wat is een variabele?

Een variabele is een naam voor een stukje geheugen waar je een waarde in bewaart.

let leeftijd = 25;      // kan later veranderen
const naam = "Sophie"; // verandert niet
console.log(naam, leeftijd);
  • Namen: geen spaties, niet starten met een cijfer, gebruik camelCase (mijnLeeftijd).
  • Gebruik const als de waarde niet hoeft te wijzigen; anders let.

Waarom let, const en var?

  • const → vaste waarde, niet overschrijfbaar.
  • let → veranderbare waarde, modern gebruik.
  • var → ouderwets, kan bugs veroorzaken, vermijden.

const – constante waarden

const PI = 3.14159;
PI = 3.15; // ❌ Fout: kan niet overschrijven

const naam = "Lisa";
console.log(naam); // "Lisa"

Gebruik const standaard, tenzij je echt weet dat de waarde later verandert.

let – veranderbare waarden

let score = 0;
score = 10; // ✅ toegestaan
score = score + 5; // ✅
console.log(score); // 15

Gebruik let voor waarden die later kunnen wijzigen.

Variabelen updaten

let a = 0;
a = a + 1; // stap voor stap optellen
console.log(a); // 1

Je pakt de huidige waarde, telt er iets bij op, en slaat het terug op in dezelfde variabele.

Verkorte notatie

let a = 0;
a += 1; // zelfde als a = a + 1
a -= 2; // a = a - 2
a *= 3; // a = a * 3
a /= 4; // a = a / 4

Handig bij veel rekenoperaties.

a++ en a--

let a = 0;
a++; // verhoogt met 1
console.log(a); // 1

a--; // verlaagt met 1
console.log(a); // 0

a++ en a-- zijn veelgebruikte, snelle manieren om te verhogen of te verlagen.

Prefix vs postfix

let x = 5;
console.log(x++); // 5, daarna x=6
console.log(++x); // 7, eerst verhogen dan tonen

Wees bewust van het verschil! ++x verhoogt eerst, x++ toont eerst de oude waarde.

Best practices

  • Gebruik const standaard, let alleen als de waarde moet veranderen.
  • Vermijd var, tenzij je expliciet begrijpt waarom.
  • Gebruik verkorte operatoren voor duidelijkere code: +=, -=, a++.

Waarde‑types in JavaScript

  • Primitieven: number, string, boolean, null, undefined, bigint, symbol
  • Referenties: object (incl. arrays en functies)
let n = 42;                 // number
let tekst = `Hallo`;        // string (template literal)
let waar = true;            // boolean
let niks = null;            // null
let onbekend;               // undefined
let lijst = [1,2,3];        // array (object)

Type‑conversie & valkuilen

Number("123")   // 123
String(123)      // "123"
Boolean(0)       // false, Boolean(1) === true

Number("abc")    // NaN (Not a Number)

// Let op met + : optellen vs concateneren
console.log(1 + 2);         // 3
console.log("1" + 2);       // "12" (string!)

Gebruik altijd expliciete conversie als je twijfelt.

Template literals

const naam = "Aya";
const punten = 7;
console.log(`Hoi ${naam}, je hebt ${punten} punten`);

Backticks (`) i.p.v. quotes, met ${...} voor expressies.

Scope & de "Temporal Dead Zone"

{
  console.log(x); // ❌ ReferenceError (TDZ)
  let x = 5;
}
  • Variabelen met let/const bestaan pas na de declaratie.
  • Hou declaraties zo dicht mogelijk bij gebruik.

Best practices

  • Gebruik const standaard, let wanneer nodig.
  • Naamgeving: duidelijk & beschrijvend (aantalPogingen).
  • Vermijd magische getallen: maak er constante variabelen van.
  • Log tussentijds met console.log bij het debuggen.

Gebruikersinput met readline

const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

rl.question('Wat is je naam? ', (naam) => {
  console.log(`Hallo ${naam}!`);
  rl.close();
});

Dit is asynchroon: de callback wordt later uitgevoerd.

Een handige prompt() helper

Met een Promise kunnen we await gebruiken voor leesbare lussen.

const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });

function prompt(vraag) {
  return new Promise(resolve => rl.question(vraag, resolve));
}

(async function main(){
  const naam = await prompt('Naam: ');
  console.log('Hallo', naam);
  rl.close();
})();

Tip: Sla dit op als app.mjs of run met node --input-type=module voor top‑level await. In dit voorbeeld gebruiken we een IIFE.

while(true) basis

let teller = 0;
while (true) {
  teller++;
  console.log('Poging', teller);
  if (teller === 5) {
    console.log('Breek uit de lus');
    break; // stopt de lus
  }
}
console.log('Klaar');
  • while(true) = oneindige lus
  • break = spring eruit
  • continue = sla rest van deze iteratie over

⚠️ Gevaar: drukke CPU‑lus

// ❌ Dit blokkeert je programma (en vreet CPU)
while (true) {
  // geen I/O, geen pauze, geen break
}

Gebruik while(true) alleen met een duidelijke break‑voorwaarde of met I/O (bijv. gebruikersinput).

Veilige input‑lus (callback‑stijl)

const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
let teller = 0;

function vraagNaam(){
  rl.question("Typ je naam (of 'stop'): ", (naam) => {
    if (naam === 'stop') { console.log('Gestopt'); rl.close(); return; }
    teller++;
    console.log(`Hallo ${naam}! (#${teller})`);
    vraagNaam(); // herhaal
  });
}

vraagNaam();

Dit lijkt op while(true), maar gebruikt herhaalde vragen (asynchrone I/O) i.p.v. een drukke CPU‑lus.

Veilige input‑lus (async/await)

const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const prompt = (q) => new Promise(res => rl.question(q, res));

(async function main(){
  let count = 0;
  while (true) {
    const txt = await prompt("Geef iets (of 'stop'): ");
    if (txt === 'stop') break;
    count++;
    console.log(`Je tikte: ${txt} (totaal: ${count})`);
  }
  console.log('Tot ziens!');
  rl.close();
})();

Hier is while(true) oké omdat elke iteratie wacht op input (geen CPU‑spin).

break & continue

for (let i = 1; i <= 10; i++) {
  if (i % 2 === 0) continue; // sla even nummers over
  if (i > 7) break;          // stop helemaal
  console.log(i);            // 1,3,5,7
}

Oefening 1 – tel geldige getallen

  1. Vraag de gebruiker herhaaldelijk om een getal.
  2. Typt de gebruiker stop? Breek uit de lus.
  3. Is de invoer een geldig getal? Tel op bij aantalGeldig.
  4. Toon op het einde hoeveel geldige getallen er waren.

Hint: gebruik Number(input) en controleer met Number.isNaN(...).

Oefening 2 – som & gemiddelde

  1. Breid oefening 1 uit: bewaar ook de som van alle geldige getallen.
  2. Toon na stop zowel aantal, som als gemiddelde.

Oefening 3 – beperk de lus

  1. Laat de lus maximaal 10 invoeren accepteren.
  2. Breek ook als de gebruiker 3× na elkaar ongeldig typt.

Zo leer je veiligheidsrails bouwen voor je lussen.

Mini‑project – Raad het getal

Maak een spelletje dat een geheim getal tussen 1 en 100 kiest.

  • De speler raadt; het programma zegt hoger of lager.
  • Gebruik while(true) en breek bij goed antwoord.
  • Tel het aantal pogingen en toon die bij winst.
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const prompt = (q) => new Promise(res => rl.question(q, res));

(async function main(){
  const geheim = 1 + Math.floor(Math.random()*100);
  let pogingen = 0;
  while (true) {
    const invoer = await prompt('Raad (1-100) of "stop": ');
    if (invoer === 'stop') { console.log('Jammer!'); break; }
    const gok = Number(invoer);
    if (Number.isNaN(gok)) { console.log('Geen geldig getal.'); continue; }
    pogingen++;
    if (gok === geheim) { console.log(`Juist in ${pogingen} pogingen!`); break; }
    console.log(gok < geheim ? 'Hoger...' : 'Lager...');
  }
  rl.close();
})();

Runnen & debuggen

  • Script uitvoeren: node app.js
  • Automatisch herstarten bij wijzigingen: node --watch app.js (nieuwere Node)
  • Stoppen in de terminal: Ctrl+C
  • Log variabelen met console.log('x=', x)

Samenvatting

  • Variabelen bewaren waarden; kies const tenzij je moet wijzigen.
  • Types & conversies: let op NaN en string‑concatenatie.
  • readline voor gebruikersinput (asynchroon!).
  • while(true) met duidelijke break‑voorwaarde of I/O‑wachtmomenten.

Starter‑template (kopieerbaar)

// app.js
const readline = require('readline');
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
const ask = (q) => new Promise(res => rl.question(q, res));

(async function main(){
  // TODO: jouw code hier
  let count = 0;
  while (true) {
    const s = await ask("Input (of 'stop'): ");
    if (s === 'stop') break;
    count++;
    console.log('Invoer', count, ':', s);
  }
  console.log('Klaar. Aantal invoeren:', count);
  rl.close();
})();