{
  "assessmentTests": {
    "javascript_test": {
      "name": "JavaScript-test",
      "desc": "30 scenariogebaseerde vragen over kernstructuur en typeomzetting, functies/bereik/closures en this, objecten/arrays en datastructuren, en event loop/async/prototype idiomen — ontdek of uw JavaScript-vaardigheden aansluiten bij wat vacatureberichten bedoelen met JavaScript-competentie.",
      "recommendation": "Uw JavaScript-competentieprofiel",
      "results": {
        "beginner": {
          "name": "Beginner",
          "desc": "U kunt werkende functies en objecten schrijven, maar de vragen die u miste concentreren zich rond typeomzetting en referentiesemantieken in plaats van syntaxis — == die stilletjes types omzet voor het vergelijken, een array-toewijzing die één object deelt in plaats van het te kopiëren, waarom NaN nooit gelijk is aan zichzelf. Dit gaat niet over slecht zijn in JavaScript; dit zijn de specifieke regels die mensen verwarren die de taal hebben geleerd door code te schrijven die toevallig werkte in plaats van te leren hoe waarden en referenties werkelijk gedragen. Ze zijn belangrijk op het werk omdat elk geval een plaats is waar code zonder fout wordt uitgevoerd maar toch het verkeerde doet.",
          "recommendation": "Begin met drie dingen, in deze volgorde: waarom == types omzet voor het vergelijken terwijl === dat niet doet, waarom het toewijzen van een array of object aan een nieuwe variabele de referentie kopieert in plaats van de waarde, en hoe var wordt opgeheven en geïnitialiseerd met undefined terwijl let en const in de temporele dode zone blijven tot hun verklaring daadwerkelijk wordt uitgevoerd. MDN's JavaScript-gids behandelt alle drie met uitvoerbare voorbeelden."
        },
        "intermediate": {
          "name": "Intermediair",
          "desc": "U voert dagelijkse toepassingscode comfortabel uit — functies, array-methoden, rechtlijnige controleflow — en zou niet worden vertraagd door routinematige functiewerkzaamheden. De kloof tussen hier en Geavanceerd is vooral wat er gebeurt wanneer JavaScripts bereiks- en timinregels samenkomen: een var die in callbacks van een lus wordt vastgelegd, die allemaal dezelfde eindwaarde lezen, een this die stil stopt met naar het object te verwijzen zodra een methode ervan wordt losgekoppeld, een spread-kopie die diep lijkt maar slechts één niveau kopieert. Dit zijn soorten bugs die een snelle doorbladerde doorstaan en alleen onder specifieke runtimeomstandigheden verschijnen.",
          "recommendation": "Concentreer u op hoe bereik en this werkelijk worden opgelost op het moment van aanroep in plaats van op het moment van definitie: waarom een var-gebaseerde for-lus elke callback dezelfde eindtellerswaarde geeft terwijl let dat niet doet, hoe this wordt bepaald door hoe een functie wordt aangeroepen in plaats van waar deze is geschreven, en waarom een spread of Object.assign alleen het bovenste niveau van een object kopieert. Daarna de event loop, omdat dat is wat mensen verwarrt die promises al afzonderlijk kennen."
        },
        "advanced": {
          "name": "Geavanceerd",
          "desc": "Dit is het niveau dat de meeste vacatureberichten bedoelen met 'sterke JavaScript'. U leest een keten van filter/map/reduce en kunt exact voorspellen wat deze teruggeeft zonder de originele array te wijzigen, u weet waarom een synchrone console.log altijd een microtask verslaat die altijd een setTimeout verslaat, en u grijpt naar Promise.all wetende dat het onmiddellijk afwijst zodra één promise afwijkt in plaats van op de rest te wachten. Wat deze band van de top onderscheidt is de prototype- en objectmodelkant van het werk: hoe de prototypeketen een overgeërfde methode oplost tegenover hasOwnProperty, en wat een privéveld in een klasse werkelijk verborgen houdt.",
          "recommendation": "Duik in de delen die toestand beschermen die andere code ook aanraakt: hoe JavaScripts prototypeketen methode-lookups oplost die niet op het geval zelf voorkomen, wat de privé #fields van een klasse werkelijk verborgen houden voor externe toegang, en hoe JSON.stringify undefined en functies anders behandelt binnen een normaal object versus binnen een array. MDN's materiaal over de event loop en de prototypeketen is de natuurlijke volgende stap voor beide."
        },
        "expert": {
          "name": "Expert",
          "desc": "U scoorde aan de top van elk onderdeel — kernstructuur, typen en omzetting; functies, bereik, closures en this; objecten, arrays en datastructuren; en async, event loop, prototypes en idiomen. Praktisch gezien betekent dit dat u van iemand anders een functie krijgt en kunt uitleggen waarom deze teruggeeft wat zij teruggeeft, niet alleen wat de syntaxis zegt dat zij zou moeten doen, wat de moeilijkere en waardevolledere vaardigheid is. Op dit niveau is de taal zelf zelden de beperkende factor; de limiet is meestal async-controleflow of de vorm van de gegevens eronder.",
          "recommendation": "De retournen zitten nu in ontwerp en diagnose: redeneren over een race condition tussen Promise.all en Promise.race in plaats van hun definities op te zeggen, kiezen wanneer een closure het juiste gereedschap is voor privétoestand tegenover wanneer het privéveld van een klasse, en het lezen van een microtask-versus-macrotask orderingbug in productielogs in plaats van in een quiz. Beschrijf een timingebug die u hebt gevonden — een verouderde sluitingsvariabele of een async-callback in de verkeerde volgorde — in plaats van JavaScript-functies een naam te geven; dit toont het redeneren aan, niet alleen het vocabulaire."
        }
      },
      "questions": [
        {
          "question": "console.log(x);\nvar x = 5;\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "5 — var-verklaringen worden onmiddellijk uitgevoerd, vóór andere code"},
            {"icon": "","label": "ReferenceError: x is not defined"},
            {"icon": "","label": "undefined — var-verklaringen worden naar de top van hun bereik opgeheven en geïnitialiseerd met undefined, maar de toewijzing wordt ter plekke uitgevoerd, dus voordat deze wordt uitgevoerd, bestaat de variabele maar bevat undefined"},
            {"icon": "","label": "null"}
          ]
        },
        {
          "question": "console.log(y);\nlet y = 5;\nWat gebeurt er?",
          "options": [
            {"icon": "","label": "Het genereert ReferenceError: Cannot access 'y' before initialization — let wordt naar de top van zijn bereik opgeheven maar blijft in de temporele dode zone totdat de verklaringslijn daadwerkelijk wordt uitgevoerd"},
            {"icon": "","label": "Het geeft undefined af, hetzelfde als var zou doen"},
            {"icon": "","label": "Het geeft 5 af"},
            {"icon": "","label": "Het genereert een SyntaxError bij het parsen"}
          ]
        },
        {
          "question": "const arr = [1, 2, 3];\narr.push(4);\nconsole.log(arr.length);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "4 — const voorkomt alleen het opnieuw toewijzen van de arr-binding zelf, niet het wijzigen van het array-object waarnaar het wijst, dus push werkt nog steeds"},
            {"icon": "","label": "Het genereert een TypeError, omdat arr const is"},
            {"icon": "","label": "3 — push is geblokkeerd op een const-array"},
            {"icon": "","label": "undefined"}
          ]
        },
        {
          "question": "console.log('' == 0);\nconsole.log('' === 0);\nWat geven de twee regels af?",
          "options": [
            {"icon": "","label": "true en true"},
            {"icon": "","label": "false en false"},
            {"icon": "","label": "true daarna false — == converteert de lege string naar 0 vóór het vergelijken, terwijl === type en waarde vergelijkt zonder omzetting, en een string is nooit strikt gelijk aan een getal"},
            {"icon": "","label": "false daarna true"}
          ]
        },
        {
          "question": "console.log(NaN === NaN);\nconsole.log(Number.isNaN(NaN));\nWat geven de twee regels af?",
          "options": [
            {"icon": "","label": "true en true"},
            {"icon": "","label": "true en false"},
            {"icon": "","label": "false en false"},
            {"icon": "","label": "false daarna true — NaN is de enige waarde in JavaScript die niet gelijk is aan zichzelf onder ===, maar Number.isNaN() detecteert het toch correct"}
          ]
        },
        {
          "question": "console.log(typeof null);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "\"null\""},
            {"icon": "","label": "\"object\" — een langdurige bug in de taal: typeof null geeft \"object\" terug hoewel null een primitief is, en het is behouden gebleven vanwege achterwaartse compatibiliteit sinds die tijd"},
            {"icon": "","label": "\"undefined\""},
            {"icon": "","label": "\"boolean\""}
          ]
        },
        {
          "question": "Welk van het volgende is waarheidsgetrouw wanneer gebruikt in een if-voorwaarde?",
          "options": [
            {"icon": "","label": "0"},
            {"icon": "","label": "\"\" (een lege string)"},
            {"icon": "","label": "null"},
            {"icon": "","label": "\"0\" — een niet-lege string is altijd waarheidsgetrouw in JavaScript, zelfs als de inhoud de string \"0\" zelf is"}
          ]
        },
        {
          "question": "foo();\nfunction foo() { console.log('a'); }\nbar();\nvar bar = function() { console.log('b'); };\nWat gebeurt er?",
          "options": [
            {"icon": "","label": "Beide aanroepen geven af, \"a\" daarna \"b\""},
            {"icon": "","label": "foo() geeft \"a\" af; bar() genereert TypeError: bar is not a function — functiedeclaraties worden volledig opgeheven met hun lichaam, maar een var-toegewezen functie-expressie heft alleen de var zelf op (als undefined), niet de toewijzing"},
            {"icon": "","label": "Beide aanroepen genereren ReferenceError"},
            {"icon": "","label": "foo() genereert; bar() geeft \"b\" af"}
          ]
        },
        {
          "question": "function makeCounter() {\n  let count = 0;\n  return function() { count++; return count; };\n}\nconst counter = makeCounter();\nconsole.log(counter());\nconsole.log(counter());\nWat geven de twee regels af?",
          "options": [
            {"icon": "","label": "1 daarna 1"},
            {"icon": "","label": "0 daarna 1"},
            {"icon": "","label": "undefined daarna undefined"},
            {"icon": "","label": "1 daarna 2 — de geretourneerde functie sluit over dezelfde count-variabele uit het bereik van makeCounter, en die variabele blijft tussen aanroepen in plaats van opnieuw in te stellen"}
          ]
        },
        {
          "question": "for (var i = 0; i < 3; i++) {\n  setTimeout(() => console.log(i), 0);\n}\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "0, 1, 2"},
            {"icon": "","label": "3, 3, 3 — var is functiebereich, niet blokbereich, dus alle drie callbacks sluiten over dezelfde i, die de lus al heeft voltooid en gelijk is aan 3 wanneer een van hen daadwerkelijk wordt uitgevoerd"},
            {"icon": "","label": "0, 0, 0"},
            {"icon": "","label": "undefined, undefined, undefined"}
          ]
        },
        {
          "question": "for (let i = 0; i < 3; i++) {\n  setTimeout(() => console.log(i), 0);\n}\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "3, 3, 3"},
            {"icon": "","label": "0, 0, 0"},
            {"icon": "","label": "undefined, undefined, undefined"},
            {"icon": "","label": "0, 1, 2 — let maakt een verse binding van i voor elk iteratie van de lus, dus elke callback sluit over zijn eigen afzonderlijke kopie in plaats van een gedeelde variabele"}
          ]
        },
        {
          "question": "function greet() { return `Hi, ${this.name}`; }\nconst person = { name: 'Ana' };\nconsole.log(greet.call(person));\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "\"Hi, Ana\" — Function.prototype.call roept de functie aan met this expliciet ingesteld op zijn eerste argument, dus this.name lost op tegen person"},
            {"icon": "","label": "\"Hi, undefined\" — call() werkt alleen op functies die al methoden van een object zijn"},
            {"icon": "","label": "Het genereert een TypeError, omdat greet geen methode van person is"},
            {"icon": "","label": "\"Hi, ${this.name}\" — call() evalueert de template literal niet"}
          ]
        },
        {
          "question": "const timer = {\n  seconds: 0,\n  start: function() {\n    setInterval(() => { this.seconds++; }, 1000);\n  },\n};\nWaarom geven mensen de voorkeur aan de pijlfunctie boven function() { this.seconds++ } binnen setInterval hier?",
          "options": [
            {"icon": "","label": "Pijlfuncties hebben hun eigen this niet — ze vangen this lexicaal op van de omsluitende start-functie, wat timer is (omdat start werd aangeroepen als timer.start()), dus this.seconds verwijst correct naar timer.seconds bij elke tick"},
            {"icon": "","label": "Pijlfuncties worden sneller uitgevoerd dan normale functies tijdens runtime"},
            {"icon": "","label": "Pijlfuncties binden automatisch this aan het globale object, wat toevallig gelijk is aan timer"},
            {"icon": "","label": "Pijlfuncties converteren this automatisch naar een globale variabele"}
          ]
        },
        {
          "question": "function multiply(a, b) { return a * b; }\nconst double = multiply.bind(null, 2);\nconsole.log(double(5));\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "Het genereert een fout, omdat bind beide argumenten vooraf vereist"},
            {"icon": "","label": "10 — bind retourneert een nieuwe functie met this en alle voorloopargumenten vooraf ingesteld; het aanroepen van double(5) levert het resterende argument b=5, dus multiply(2, 5) wordt uitgevoerd"},
            {"icon": "","label": "NaN"},
            {"icon": "","label": "7, omdat bind zijn argumenten aan de aanroep toevoegt in plaats van deze te vervangen"}
          ]
        },
        {
          "question": "function outer() {\n  let x = 10;\n  function inner() {\n    let x = 20;\n    console.log(x);\n  }\n  inner();\n  console.log(x);\n}\nouter();\nWat geven de twee console.log-aanroepen af?",
          "options": [
            {"icon": "","label": "20 daarna 20"},
            {"icon": "","label": "20 daarna 10 — inner's eigen let x schaduwt outer's x alleen binnen inner's bereik; outer's eigen x wordt nooit aangeraakt"},
            {"icon": "","label": "10 daarna 10"},
            {"icon": "","label": "Het genereert een ReferenceError, omdat x twee keer is gedeclareerd"}
          ]
        },
        {
          "question": "const a = [1, 2, 3];\nconst b = a;\nb.push(4);\nconsole.log(a.length);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "3 — b is een aparte kopie van a"},
            {"icon": "","label": "undefined"},
            {"icon": "","label": "Het genereert een TypeError, omdat a const is"},
            {"icon": "","label": "4 — arrays zijn objecten, dus const b = a kopieert de referentie, niet de array; het wijzigen van b via push wijzigt ook exact dezelfde array waar a naar wijst"}
          ]
        },
        {
          "question": "const original = { name: 'Ana', tags: ['x', 'y'] };\nconst copy = { ...original };\ncopy.name = 'Bea';\ncopy.tags.push('z');\nconsole.log(original.name, original.tags.length);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "'Ana' 2 — spread maakt een diepe kopie van elk genest object en array"},
            {"icon": "","label": "'Ana' 3 — spread is slechts een oppervlakkige kopie: een primitieve eigenschap zoals name wordt volgens waarde gekopieerd, dus het opnieuw toewijzen van copy.name raakt nooit original, maar een geneste array zoals tags wordt volgens referentie gekopieerd, dus het pushen naar copy.tags wijzigt exact dezelfde array waar original.tags naar wijst"},
            {"icon": "","label": "'Bea' 3 — spread kopieert alles volgens referentie, dus zowel wijzigingen op het hoogste niveau als geneste wijzigingen worden teruggevoerd naar original"},
            {"icon": "","label": "'Bea' 2"}
          ]
        },
        {
          "question": "const { a: x = 10, b: y = 20 } = { a: 5 };\nconsole.log(x, y);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "undefined undefined"},
            {"icon": "","label": "5 undefined"},
            {"icon": "","label": "10 20"},
            {"icon": "","label": "5 20 — a wordt hernoemd naar x en is aanwezig, dus het houdt zijn waarde 5; b wordt hernoemd naar y en is afwezig, dus het valt terug op zijn standaard 20"}
          ]
        },
        {
          "question": "const [first, ...rest] = [1, 2, 3, 4];\nconsole.log(rest);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "[1, 2, 3, 4]"},
            {"icon": "","label": "[2, 3, 4] — rest verzamelt elk overblijvend element na first in een gloednieuwe array"},
            {"icon": "","label": "2"},
            {"icon": "","label": "[1]"}
          ]
        },
        {
          "question": "const nums = [10, 1, 2];\nnums.sort();\nconsole.log(nums);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "[1, 2, 10] — sort ordent altijd getallen numeriek in oplopende volgorde bij standaard"},
            {"icon": "","label": "[10, 1, 2] — sort wijzigt de originele array niet"},
            {"icon": "","label": "[1, 10, 2] — Array.prototype.sort's standaardcomparator converteert elementen naar strings en vergelijkt deze lexicografisch, dus \"10\" wordt vóór \"2\" gesorteerd; sort wijzigt ook de array ter plekke in plaats van een nieuwe te retourneren"},
            {"icon": "","label": "[2, 1, 10]"}
          ]
        },
        {
          "question": "const user = { profile: { age: 0 } };\nconsole.log(user.profile?.age ?? 'unknown');\nconsole.log(user.address?.city ?? 'unknown');\nWat geven de twee regels af?",
          "options": [
            {"icon": "","label": "'unknown' daarna 'unknown' — ?? behandelt 0 als ontbrekend, hetzelfde als || doet"},
            {"icon": "","label": "0 daarna 'unknown' — ?? valt alleen terug op null of undefined, niet op andere onjuiste waarden zoals 0, dus age (0) wordt ongewijzigd gehouden; user.address is undefined, dus ?. kortsluiten de hele keten naar undefined en ?? levert vervolgens 'unknown'"},
            {"icon": "","label": "0 daarna undefined"},
            {"icon": "","label": "'unknown' daarna 0"}
          ]
        },
        {
          "question": "const obj = { a: undefined, b: function(){}, c: NaN, d: [undefined, function(){}, 1] };\nconsole.log(JSON.stringify(obj));\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "'{\"a\":null,\"b\":null,\"c\":null,\"d\":[null,null,1]}' — elke niet-ondersteunde waarde wordt overal null, in objecten en arrays"},
            {"icon": "","label": "'{\"a\":undefined,\"b\":undefined,\"c\":NaN,\"d\":[undefined,null,1]}'"},
            {"icon": "","label": "'{\"c\":null,\"d\":[null,null,1]}' — objecteigenschappen waarvan de waarde undefined of een functie is, worden volledig weggelaten, en NaN wordt geserialiseerd als null, maar binnen een array worden dezelfde niet-ondersteunde waarden null in plaats van te worden verwijderd, omdat het verwijderen van een array-element elk later index zou verschuiven"},
            {"icon": "","label": "Het genereert een TypeError, omdat NaN niet kan worden geserialiseerd naar JSON"}
          ]
        },
        {
          "question": "console.log('1');\nsetTimeout(() => console.log('2'), 0);\nPromise.resolve().then(() => console.log('3'));\nconsole.log('4');\nIn welke volgorde worden deze afgeprint?",
          "options": [
            {"icon": "","label": "1, 2, 3, 4"},
            {"icon": "","label": "1, 4, 2, 3"},
            {"icon": "","label": "1, 4, 3, 2 — synchrone code wordt eerst uitgevoerd (dus 1 en 4 worden onmiddellijk afgeprint), vervolgens wordt de microtaskwachtrij volledig leeggemaakt voordat de event loop naar de volgende macrotask gaat, dus 3 wordt afgeprint vóór de setTimeout-callback's 2"},
            {"icon": "","label": "1, 3, 4, 2"}
          ]
        },
        {
          "question": "async function foo() {\n  console.log('a');\n  await null;\n  console.log('b');\n}\nconsole.log('start');\nfoo();\nconsole.log('end');\nIn welke volgorde worden deze afgeprint?",
          "options": [
            {"icon": "","label": "start, a, end, b — foo() wordt synchroon tot zijn eerste await uitgevoerd, dus 'a' wordt onmiddellijk afgeprint wanneer foo() wordt aangeroepen; await onderbreekt vervolgens foo en geeft controle terug aan de aanroeper, dus 'end' wordt afgeprint vóór de hervatting van 'b', die later als microtask wordt uitgevoerd"},
            {"icon": "","label": "start, a, b, end"},
            {"icon": "","label": "start, end, a, b"},
            {"icon": "","label": "a, start, end, b"}
          ]
        },
        {
          "question": "Promise.all([\n  Promise.resolve(1),\n  Promise.reject('err'),\n  Promise.resolve(3),\n]).then(r => console.log('ok', r)).catch(e => console.log('fail', e));\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "'fail err' — Promise.all wijst af zodra een van zijn invoer-promises afwijkt, en negeert de resultaten van de andere, dus de catch-handler wordt uitgevoerd met die afwijzingsreden"},
            {"icon": "","label": "'ok' [1, 3]"},
            {"icon": "","label": "'ok' [1, undefined, 3]"},
            {"icon": "","label": "Het genereert synchroon en geen handler wordt ooit uitgevoerd"}
          ]
        },
        {
          "question": "const fast = new Promise(res => setTimeout(() => res('fast'), 10));\nconst slow = new Promise(res => setTimeout(() => res('slow'), 100));\nPromise.race([fast, slow]).then(v => console.log(v));\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "'slow'"},
            {"icon": "","label": "['fast', 'slow']"},
            {"icon": "","label": "'fast' — Promise.race wordt afgewikkeld zodra de eerste van zijn invoer-promises wordt afgewikkeld, en de 10ms-timer lost veel eerder op dan de 100ms"},
            {"icon": "","label": "Het genereert een fout, omdat race precies twee promises vereist"}
          ]
        },
        {
          "question": "function Animal(name) { this.name = name; }\nAnimal.prototype.speak = function() { return `${this.name} makes a sound`; };\nconst dog = new Animal('Rex');\nconsole.log(dog.speak());\nconsole.log(dog.hasOwnProperty('speak'));\nWat geven de twee regels af?",
          "options": [
            {"icon": "","label": "'Rex makes a sound' daarna true"},
            {"icon": "","label": "undefined daarna false"},
            {"icon": "","label": "Het genereert een TypeError, omdat dog geen eigen speak-methode heeft"},
            {"icon": "","label": "'Rex makes a sound' daarna false — speak wordt gedefinieerd op Animal.prototype, niet op het dog-geval zelf; dog vindt het via de prototypeketen wanneer het wordt aangeroepen, maar hasOwnProperty controleert alleen de eigen eigenschappen van het geval, niet iets overgeërfd"}
          ]
        },
        {
          "question": "class Counter {\n  #count = 0;\n  increment() { this.#count++; return this.#count; }\n}\nconst c = new Counter();\nconsole.log(c.increment());\nconsole.log(c.count);\nWat geven de twee regels af?",
          "options": [
            {"icon": "","label": "1 daarna undefined — #count is een privé-klasseveld, leesbaar en schrijfbaar alleen van binnen de eigen methoden van de klasse; c.count (zonder #) is een geheel ander, gewoon eigendom dat nooit is ingesteld, dus het is undefined"},
            {"icon": "","label": "1 daarna 0"},
            {"icon": "","label": "1 daarna 1"},
            {"icon": "","label": "Het genereert een SyntaxError bij toegang tot c.count"}
          ]
        },
        {
          "question": "const items = ['a', 'b'];\nconst label = `Items: ${items.length > 0 ? items.join(', ') : 'none'}`;\nconsole.log(label);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "'Items: ${items.length > 0 ? items.join(\\', \\') : \\'none\\'}'"},
            {"icon": "","label": "'Items: none'"},
            {"icon": "","label": "'Items: a, b' — template literals evalueren alle uitdrukkingen die in ${...} staan, inclusief een volledige ternaire, en interpoleren het resultaat rechtstreeks in de string"},
            {"icon": "","label": "Het genereert een SyntaxError, omdat ternaires niet zijn toegestaan in template literals"}
          ]
        },
        {
          "question": "const nums = [1, 2, 3, 4, 5];\nconst result = nums.filter(n => n % 2 === 0).map(n => n * 10).reduce((sum, n) => sum + n, 0);\nconsole.log(result, nums);\nWat wordt afgeprint?",
          "options": [
            {"icon": "","label": "60 [1, 2, 3, 4, 5] — filter, map en reduce retourneren elk een nieuwe array of waarde zonder de originele array te wijzigen, dus nums is ongewijzigd terwijl result de uiteindelijke gereduceerde som is (2 en 4, verdubbeld tot 20 en 40, opgeteld tot 60)"},
            {"icon": "","label": "60 [2, 4, 20, 40]"},
            {"icon": "","label": "150 [1, 2, 3, 4, 5]"},
            {"icon": "","label": "60 [20, 40]"}
          ]
        }
      ],
      "optionOrderVersion": "50fc0eba818f2d72"
    }
  }
}
