Ontdek de kracht van moderne JavaScript om efficiëntere, leesbaardere en robuustere webapplicaties te bouwen.
Deze gids neemt u mee door de essentiële features van ECMAScript 2015 (ES6) en verder, inclusief de nieuwste toevoegingen tot en met het huidige jaar 2026. Leer hoe u uw ontwikkelingsworkflow kunt optimaliseren met de best practices van vandaag.
INHOUDSOPGAVE
01Inleiding tot Moderne JavaScript (ES2015+)
02Essentiële Moderne Syntaxis
03Asynchrone Programmering met Moderne JavaScript
04Modules (ES Modules)
05Nieuwere Features (ES2020+)
06Best Practices en Adoptie
07Voorbehouden en Disclaimer
Inleiding tot Moderne JavaScript (ES2015+)
Sinds de release van ECMAScript 2015 (ES6) heeft JavaScript een revolutionaire transformatie ondergaan. Deze update bracht een reeks nieuwe features en syntactische suiker die de manier waarop we JavaScript schrijven fundamenteel heeft veranderd. Sindsdien zijn er jaarlijkse updates, waardoor de taal blijft evolueren en zich aanpast aan de moderne ontwikkelingsbehoeften. Het begrijpen en toepassen van deze moderne features is essentieel voor elke JavaScript-ontwikkelaar in 2026.
Deze sectie biedt een overzicht van de impact van deze veranderingen en waarom het cruciaal is om op de hoogte te blijven van de nieuwste ontwikkelingen.
Waarom Moderne JavaScript Belangrijk Is
Moderne JavaScript verbetert de productiviteit en codekwaliteit aanzienlijk. Het introduceert concepten die de code leesbaarder, onderhoudbaarder en minder foutgevoelig maken. Denk aan de overgang van callback-hel naar Promises en async/await, wat asynchrone operaties veel eenvoudiger maakt. Bovendien stimuleert het gebruik van modules een betere architectuur door code te organiseren in herbruikbare componenten.
Volgens een enquête van Stack Overflow in 2025 gaf 70% van de ontwikkelaars aan dat het gebruik van moderne JavaScript-features hun ontwikkelingssnelheid met minimaal 15% heeft verhoogd.
Korte Geschiedenis van ECMAScript
ECMAScript is de specificatie waarop JavaScript is gebaseerd. Na jaren van relatieve stilstand na ES5 (2009), kwam ES2015 (ook bekend als ES6) als een belangrijke mijlpaal. Deze release introduceerde onder andere let/const, arrow functions, classes, modules en Promises. Vanaf 2016 zijn er jaarlijkse releases van ECMAScript, aangeduid als ES2016, ES2017, enzovoort, die incrementele verbeteringen en nieuwe features toevoegen.
De continue evolutie zorgt ervoor dat JavaScript een relevante en krachtige taal blijft voor webontwikkeling, server-side applicaties (Node.js) en zelfs mobiele apps (React Native).

Het beheersen van moderne JavaScript is een fundamentele vereiste voor elke professionele webontwikkelaar in 2026.
Essentiële Moderne Syntaxis
De kern van moderne JavaScript ligt in de verbeterde syntaxis die het schrijven van code intuïtiever en beknopter maakt. Deze sectie behandelt de meest gebruikte en invloedrijke syntactische vernieuwingen.
let en const
Voor ES2015 was var de enige manier om variabelen te declareren. Dit leidde vaak tot problemen met scoping en hoisting. let en const bieden block-scoping en lossen veel van deze problemen op, waardoor code voorspelbaarder wordt. const wordt gebruikt voor waarden die niet opnieuw toegewezen mogen worden, terwijl let voor variabelen is die wel kunnen veranderen.
Het gebruik van const is de standaardpraktijk wanneer een variabele na initialisatie niet meer hoeft te worden gewijzigd. Dit verhoogt de leesbaarheid en voorkomt onbedoelde mutaties. let wordt alleen gebruikt als her-toewijzing noodzakelijk is.
// Ouderwetse 'var' (functie-scoped, kan leiden tot verwarring)
var x = 10;
if (true) {
var x = 20; // x is nu 20, ook buiten de if-statement
console.log('Binnen if (var):', x); // 20
}
console.log('Buiten if (var):', x); // 20 (niet 10!)
// Moderne 'let' (block-scoped)
let y = 10;
if (true) {
let y = 20; // Nieuwe 'y' variabele, alleen geldig binnen de if-statement
console.log('Binnen if (let):', y); // 20
}
console.log('Buiten if (let):', y); // 10 (originele 'y' blijft behouden)
// Moderne 'const' (block-scoped, niet her-toewijsbaar)
const PI = 3.14159;
// PI = 3.14; // Fout: Assignment to constant variable.
const CONFIG = {
API_KEY: 'abc123xyz',
VERSION: '1.0'
};
CONFIG.VERSION = '1.1'; // Dit is toegestaan: objecteigenschappen muteren
// CONFIG = {}; // Fout: Assignment to constant variable.CODE-UITLEG: Dit voorbeeld demonstreert het verschil tussen var, let en const. var heeft functionele scoping, terwijl let en const block-scoping hebben, wat betekent dat ze alleen binnen het blok waar ze zijn gedeclareerd bestaan. const voorkomt her-toewijzing van de variabele zelf, maar laat mutatie van objecteigenschappen toe.
Arrow Functions (=>)
Arrow functions bieden een kortere syntaxis voor het schrijven van anonieme functies en lossen het problematische this-contextprobleem op in traditionele functies. Ze binden de this-waarde lexicaal, wat betekent dat this verwijst naar de context waarin de arrow function is gedefinieerd.
Dit maakt arrow functions bijzonder nuttig voor callbacks, zoals in .map(), .filter(), .reduce(), en event handlers, waar de this-context vaak verwarrend kon zijn met reguliere functies.
// Traditionele functie
function optellen(a, b) {
return a + b;
}
console.log('Traditioneel:', optellen(5, 3)); // 8
// Arrow function (beknopte syntaxis)
const aftrekken = (a, b) => a - b;
console.log('Arrow (beknopt):', aftrekken(10, 4)); // 6
// Arrow function met meerdere statements
const vermenigvuldigen = (a, b) => {
const resultaat = a * b;
return resultaat;
};
console.log('Arrow (meerdere statements):', vermenigvuldigen(2, 6)); // 12
// 'this' context in traditionele functie vs. arrow function
class Teller {
constructor() {
this.waarde = 0;
}
startTraditioneel() {
setInterval(function() {
// 'this' verwijst hier naar de globale object (window in browser) of undefined in strict mode
// console.log(this.waarde++); // Fout: this.waarde is undefined
}, 1000);
}
startModern() {
setInterval(() => {
// 'this' verwijst hier lexicaal naar de 'Teller' instantie
this.waarde++;
console.log('Teller:', this.waarde);
}, 1000);
}
}
const mijnTeller = new Teller();
// mijnTeller.startTraditioneel(); // Zou niet werken zoals verwacht
// mijnTeller.startModern(); // Werkt correctCODE-UITLEG: Arrow functions bieden een kortere syntaxis en binden de this-context lexicaal, wat betekent dat this de waarde behoudt van de omringende scope. Dit is een enorme verbetering voor functies die worden gebruikt als callbacks, zoals in setInterval.
Template Literals (` `)
Template literals, omringd door backticks (), maken het eenvoudiger om strings te maken met ingebedde expressies en multiline strings. Voorheen moest je strings concatenaten met + en \n gebruiken voor nieuwe regels, wat vaak onoverzichtelijk werd.
Met template literals kunt u variabelen en JavaScript-expressies direct in de string plaatsen met behulp van ${expressie}. Dit verbetert de leesbaarheid en vermindert de kans op fouten bij het samenstellen van complexe strings, bijvoorbeeld voor HTML-fragmenten of SQL-queries.
// Ouderwetse string concatenatie
const naamOud = 'Alice';
const leeftijdOud = 30;
const begroetingOud = 'Hallo, mijn naam is ' + naamOud + ' en ik ben ' + leeftijdOud + ' jaar oud.';
console.log(begroetingOud);
// Ouderwetse multiline string
const multilineOud = 'Dit is de eerste regel.\n' +
'Dit is de tweede regel.\n' +
'En dit de derde.';
console.log(multilineOud);
// Moderne Template Literal
const naamNieuw = 'Bob';
const leeftijdNieuw = 25;
const begroetingNieuw = `Hallo, mijn naam is ${naamNieuw} en ik ben ${leeftijdNieuw} jaar oud.`;
console.log(begroetingNieuw);
// Moderne multiline Template Literal
const multilineNieuw = `Dit is de eerste regel.
Dit is de tweede regel.
En dit de derde.`;
console.log(multilineNieuw);
// Expressies in Template Literal
const prijs = 10;
const aantal = 3;
const totaal = `Het totaalbedrag is €${prijs * aantal}.`;
console.log(totaal); // Het totaalbedrag is €30.CODE-UITLEG: Template literals (omringd door backticks) vereenvoudigen het maken van strings door het direct inbedden van variabelen en expressies met ${} en door het ondersteunen van multiline strings zonder expliciete newline-karakters.

Destructuring Assignment
Destructuring assignment is een krachtige feature waarmee u waarden uit arrays of eigenschappen van objecten kunt 'uitpakken' naar afzonderlijke variabelen. Dit vermindert repetitieve code en maakt het gemakkelijker om specifieke data uit complexe datastructuren te extraheren.
Het is bijzonder handig bij het werken met API-responses, configuratieobjecten of de props van React-componenten, waar u vaak slechts enkele specifieke waarden nodig heeft uit een groter object of array.
// Object destructuring
const gebruiker = {
id: 1,
naam: 'Jan',
email: '[email protected]',
adres: {
straat: 'Hoofdstraat 1',
stad: 'Amsterdam'
}
};
// Ouderwetse manier
// const idOud = gebruiker.id;
// const naamOud = gebruiker.naam;
// Moderne object destructuring
const { id, naam, email } = gebruiker;
console.log(id, naam, email); // 1 Jan [email protected]
// Destructuring met nieuwe variabele namen en geneste objecten
const { naam: volledigeNaam, adres: { stad } } = gebruiker;
console.log(volledigeNaam, stad); // Jan Amsterdam
// Array destructuring
const kleuren = ['rood', 'groen', 'blauw'];
// Ouderwetse manier
// const eersteKleurOud = kleuren[0];
// const tweedeKleurOud = kleuren[1];
// Moderne array destructuring
const [eersteKleur, tweedeKleur, derdeKleur] = kleuren;
console.log(eersteKleur, tweedeKleur, derdeKleur); // rood groen blau
// Array destructuring met overslaan van elementen en rest operator
const [eerste, , derde, ...restVanKleuren] = ['een', 'twee', 'drie', 'vier', 'vijf'];
console.log(eerste, derde, restVanKleuren); // een drie [ 'vier', 'vijf' ]CODE-UITLEG: Destructuring assignment maakt het mogelijk om waarden uit objecten en arrays direct toe te wijzen aan variabelen. Dit kan de code aanzienlijk vereenvoudigen en is vooral nuttig bij het werken met complexe datastructuren.
Spread en Rest Operators (...)
De spread operator (...) en de rest operator (ook ...) lijken op elkaar, maar hebben tegengestelde functies. De spread operator 'spreidt' de elementen van een iterable (zoals een array of string) of de eigenschappen van een object uit. De rest operator verzamelt daarentegen alle overige elementen in een array of overige eigenschappen in een object.
De spread operator is ideaal voor het kopiëren van arrays en objecten, het samenvoegen van collecties, en het doorgeven van een variabel aantal argumenten aan functies. De rest operator is nuttig in functieparameters om een willekeurig aantal argumenten af te handelen.
// Spread operator voor arrays
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5]; // [1, 2, 3, 4, 5]
console.log('Samengevoegde array:', arr2);
const arr3 = [0, ...arr1, 4]; // [0, 1, 2, 3, 4]
console.log('Array met elementen ertussen:', arr3);
// Kopiëren van een array (shallow copy)
const origineleArray = [1, 2, 3];
const gekopieerdeArray = [...origineleArray];
console.log('Gekopieerde array:', gekopieerdeArray);
console.log('Zijn ze hetzelfde object?', origineleArray === gekopieerdeArray); // false
// Spread operator voor objecten
const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3 }; // { a: 1, b: 2, c: 3 }
console.log('Samengevoegd object:', obj2);
const obj3 = { c: 0, ...obj1 }; // { c: 0, a: 1, b: 2 } (c wordt overschreven als het in obj1 zat)
console.log('Object met overschrijving:', obj3);
// Kopiëren van een object (shallow copy)
const origineelObject = { x: 1, y: 2 };
const gekopieerdObject = { ...origineelObject };
console.log('Gekopieerd object:', gekopieerdObject);
console.log('Zijn ze hetzelfde object?', origineelObject === gekopieerdObject); // false
// Rest operator in functieparameters
function logArgs(a, b, ...rest) {
console.log('a:', a);
console.log('b:', b);
console.log('rest:', rest); // Een array van de overige argumenten
}
logArgs(1, 2, 3, 4, 5);
// Output:
// a: 1
// b: 2
// rest: [3, 4, 5]
// Rest operator in destructuring
const [first, second, ...remaining] = [10, 20, 30, 40, 50];
console.log('First:', first); // 10
console.log('Second:', second); // 20
console.log('Remaining:', remaining); // [30, 40, 50]CODE-UITLEG: De spread operator (...) spreidt elementen van arrays of eigenschappen van objecten uit. De rest operator (ook ...) verzamelt overige elementen in een array of overige eigenschappen in een object. Ze zijn fundamenteel voor functionele programmering en immutability in JavaScript.
Het consequent toepassen van deze syntactische verbeteringen leidt tot significant leesbaardere en efficiëntere code.
Asynchrone Programmering met Moderne JavaScript
Asynchrone operaties, zoals het ophalen van data van een server of het lezen van bestanden, zijn een integraal onderdeel van webontwikkeling. Moderne JavaScript heeft de manier waarop we met asynchroniciteit omgaan drastisch verbeterd, waardoor de beruchte 'callback hell' tot het verleden behoort.
Promises
Promises zijn objecten die een uiteindelijke voltooiing (of mislukking) van een asynchrone operatie vertegenwoordigen en de resulterende waarde. Ze bieden een gestructureerde manier om asynchrone code te schrijven, met methoden zoals .then() voor succes en .catch() voor foutafhandeling.
Promises zijn de basis voor veel moderne asynchrone API's en bibliotheken en vormen de ruggengraat van async/await. Ze maken het mogelijk om meerdere asynchrone operaties te 'chainen' en hun resultaten op een leesbare manier te verwerken.
// Een Promise maken
const fetchData = (shouldSucceed) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldSucceed) {
resolve('Data succesvol opgehaald!');
} else {
reject('Fout bij het ophalen van data.');
}
}, 1000); // Simuleer een netwerkvertraging van 1 seconde
});
};
// Promise gebruiken
fetchData(true)
.then(data => {
console.log('Succes:', data); // Data succesvol opgehaald!
return 'Verwerkte data'; // Resultaat doorgeven aan de volgende .then
})
.then(processedData => {
console.log('Vervolgactie met:', processedData); // Vervolgactie met: Verwerkte data
})
.catch(error => {
console.error('Foutafhandeling:', error);
})
.finally(() => {
console.log('Operatie voltooid, ongeacht succes of falen.');
});
fetchData(false)
.then(data => {
console.log('Succes (dit wordt niet uitgevoerd):', data);
})
.catch(error => {
console.error('Foutafhandeling (falende promise):', error); // Foutafhandeling (falende promise): Fout bij het ophalen van data.
});
// Meerdere Promises parallel uitvoeren
Promise.all([fetchData(true), fetchData(true)])
.then(results => {
console.log('Alle data opgehaald:', results); // Alle data opgehaald: [ 'Data succesvol opgehaald!', 'Data succesvol opgehaald!' ]
})
.catch(error => {
console.error('Een van de Promises is mislukt:', error);
});CODE-UITLEG: Promises bieden een gestructureerde manier om asynchrone operaties te beheren. Ze hebben drie statussen (pending, fulfilled, rejected) en maken chaining van operaties met .then() en centrale foutafhandeling met .catch() mogelijk. Promise.all kan worden gebruikt om te wachten tot alle Promises in een array zijn voltooid.
async/await
async/await, geïntroduceerd in ES2017, bouwt voort op Promises en maakt asynchrone code nog gemakkelijker te lezen en te schrijven, bijna alsof het synchrone code is. Een functie gemarkeerd met async retourneert altijd een Promise. Binnen een async-functie kunt u het await-sleutelwoord gebruiken om te wachten op de voltooiing van een Promise voordat de uitvoering van de functie verdergaat.
Dit patroon is bijzonder effectief voor het sequentieel uitvoeren van asynchrone stappen en voor het afhandelen van fouten met traditionele try...catch-blokken, wat de code veel minder complex maakt dan met pure Promise chaining.
const simulateFetch = (url, delay, shouldFail = false) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(new Error(`Fout bij het ophalen van ${url}`));
} else {
resolve(`Inhoud van ${url} na ${delay}ms`);
}
}, delay);
});
};
// Gebruik van async/await
async function getMultipleData() {
try {
console.log('Start data ophalen...');
// Wacht op de eerste fetch
const data1 = await simulateFetch('https://api.example.com/data1', 1500);
console.log(data1);
// Wacht op de tweede fetch
const data2 = await simulateFetch('https://api.example.com/data2', 1000);
console.log(data2);
console.log('Alle data succesvol opgehaald!');
return [data1, data2];
} catch (error) {
console.error('Er is een fout opgetreden:', error.message);
return null;
}
}
getMultipleData(); // Roep de async functie aan
// Voorbeeld met parallelle uitvoering (niet sequentieel)
async function getParallelData() {
try {
console.log('Start parallel data ophalen...');
const [dataA, dataB] = await Promise.all([
simulateFetch('https://api.example.com/dataA', 2000),
simulateFetch('https://api.example.com/dataB', 1000)
]);
console.log('Data A:', dataA);
console.log('Data B:', dataB);
console.log('Alle parallelle data succesvol opgehaald!');
} catch (error) {
console.error('Fout bij parallelle operatie:', error.message);
}
}
getParallelData();
// Voorbeeld van foutafhandeling
async function fetchDataWithError() {
try {
const result = await simulateFetch('https://api.example.com/fout', 500, true);
console.log(result);
} catch (error) {
console.error('Gevangen fout:', error.message); // Gevangen fout: Fout bij het ophalen van https://api.example.com/fout
}
}
fetchDataWithError();CODE-UITLEG: async/await maakt asynchrone code veel leesbaarder door de syntaxis van synchrone code na te bootsen. Een async-functie retourneert altijd een Promise. await pauzeert de uitvoering van de async-functie totdat de Promise is voltooid. Fouten kunnen elegant worden afgehandeld met try...catch-blokken.
De introductie van async/await heeft de complexiteit van asynchrone JavaScript-code drastisch verminderd.

Modules (ES Modules)
ES Modules, geïntroduceerd in ES2015, bieden een gestandaardiseerd systeem voor het organiseren en hergebruiken van JavaScript-code. Voorheen waren ontwikkelaars afhankelijk van CommonJS (Node.js) of AMD (browsers) voor modulariteit, wat leidde tot fragmentatie en complexiteit. ES Modules bieden een uniforme oplossing voor zowel client-side als server-side JavaScript.
import en export
De import- en export-statements zijn de kern van ES Modules. Met export kunt u functies, klassen, variabelen en constanten beschikbaar maken vanuit een bestand. Met import kunt u deze geëxporteerde items in een ander bestand gebruiken. Dit bevordert code-organisatie, herbruikbaarheid en vermindert de kans op globale naamruimteconflicten.
Er zijn twee hoofdtypen exports: named exports (meerdere per bestand) en default exports (één per bestand). Named exports worden geïmporteerd met hun exacte naam, terwijl een default export met elke gewenste naam kan worden geïmporteerd.
// math.js
export const PI = 3.14159;
export function optellen(a, b) {
return a + b;
}
export const aftrekken = (a, b) => a - b;
export default class Rekenmachine {
vermenigvuldigen(a, b) {
return a * b;
}
}
// main.js
import { PI, optellen, aftrekken } from './math.js';
import Rekenmachine from './math.js'; // Let op: geen accolades voor default export
console.log('PI:', PI); // 3.14159
console.log('5 + 3 =', optellen(5, 3)); // 8
console.log('10 - 4 =', aftrekken(10, 4)); // 6
const mijnRekenmachine = new Rekenmachine();
console.log('2 * 6 =', mijnRekenmachine.vermenigvuldigen(2, 6)); // 12
// Alias voor named exports
import { optellen as som } from './math.js';
console.log('Som met alias:', som(7, 2)); // 9
// Alle named exports importeren als een object
import * as MathUtils from './math.js';
console.log('PI via namespace:', MathUtils.PI); // 3.14159CODE-UITLEG: Dit voorbeeld toont het gebruik van export om named en default exports te definiëren in math.js, en import om deze in main.js te gebruiken. Named exports worden met accolades geïmporteerd, default exports zonder. Aliassen en het importeren van alles als een namespace zijn ook mogelijk.
Dynamische Import
Dynamische import, geïntroduceerd in ES2020, maakt het mogelijk om modules op aanvraag te laden, in plaats van alles bij de start van de applicatie te laden. Dit is cruciaal voor performance-optimalisatie, met name voor grote applicaties. U kunt modules conditioneel laden of pas wanneer ze daadwerkelijk nodig zijn, bijvoorbeeld wanneer een gebruiker op een specifieke knop klikt.
De dynamische import()-functie retourneert een Promise die resolved met de module als een object. Dit maakt het mogelijk om 'code splitting' te implementeren, waarbij de browser alleen de code laadt die nodig is voor de initiële weergave, wat de laadtijd aanzienlijk verkort.
// dynamic_math.js
export function kwadraat(num) {
return num * num;
}
export function wortel(num) {
return Math.sqrt(num);
}
// app.js
console.log('Applicatie gestart.');
// Simuleer een gebeurtenis die dynamische import triggert
document.getElementById('berekenKnop').addEventListener('click', async () => {
console.log('Knop geklikt, module dynamisch laden...');
try {
const mathModule = await import('./dynamic_math.js');
console.log('Module geladen!');
const resultKwadraat = mathModule.kwadraat(5);
const resultWortel = mathModule.wortel(16);
console.log('Kwadraat van 5:', resultKwadraat); // 25
console.log('Wortel van 16:', resultWortel); // 4
} catch (error) {
console.error('Fout bij dynamisch laden van module:', error);
}
});
// HTML (voor context)
// CODE-UITLEG: Dynamische import laadt modules asynchroon en retourneert een Promise. Dit is ideaal voor 'code splitting' en het verbeteren van de initiële laadtijd van applicaties. De module wordt pas geladen wanneer deze daadwerkelijk nodig is, zoals na een gebruikersinteractie.
ES Modules, in het bijzonder met dynamische import, zijn essentieel voor het bouwen van schaalbare en performante applicaties.

Nieuwere Features (ES2020+)
Naast de grote veranderingen van ES2015 en ES2017, heeft ECMAScript jaarlijks kleinere, maar zeer nuttige toevoegingen gekregen. Deze features, vanaf ES2020 tot en met de huidige standaarden van 2026, helpen ontwikkelaars om nog beknoptere en robuustere code te schrijven.
Optional Chaining (?.)
Optional chaining (?.), geïntroduceerd in ES2020, maakt het veilig om toegang te krijgen tot eigenschappen van objecten of elementen van arrays die mogelijk null of undefined zijn. Voorheen moest u handmatig controleren op de aanwezigheid van elk niveau in een genest object, wat leidde tot veel &&-operatoren.
Met ?. stopt de expressie onmiddellijk en retourneert undefined als een eigenschap in de keten null of undefined is, zonder een fout te genereren. Dit is een enorme verbetering voor code die werkt met onzekere datastructuren, zoals API-responses.
const gebruikerData = {
id: 123,
naam: 'Kwonnis',
contact: {
email: '[email protected]',
telefoon: '06-12345678'
},
adres: null // Adres is null
};
// Zonder Optional Chaining (vereist veel checks)
// const emailOud = gebruikerData && gebruikerData.contact && gebruikerData.contact.email;
// console.log('Oud email:', emailOud); // [email protected]
// const postcodeOud = gebruikerData && gebruikerData.adres && gebruikerData.adres.postcode;
// console.log('Oud postcode:', postcodeOud); // undefined (geen fout)
// Met Optional Chaining
const emailNieuw = gebruikerData.contact?.email;
console.log('Nieuw email:', emailNieuw); // [email protected]
const postcodeNieuw = gebruikerData.adres?.postcode;
console.log('Nieuw postcode:', postcodeNieuw); // undefined
const bedrijfNaam = gebruikerData.bedrijf?.naam; // bedrijf is undefined
console.log('Bedrijf naam:', bedrijfNaam); // undefined
// Optional chaining met functieaanroep
const methode = gebruikerData.contact?.getContactInfo;
// methode(); // Dit zou een fout geven als getContactInfo niet bestaat
const resultaatMethode = gebruikerData.contact?.getContactInfo?.(); // Veilig aanroepen
console.log('Resultaat methode:', resultaatMethode); // undefined (geen fout)CODE-UITLEG: Optional chaining (?.) maakt het veilig om toegang te krijgen tot geneste objecteigenschappen of methoden. Als een eigenschap in de keten null of undefined is, stopt de expressie en retourneert undefined, zonder een TypeError te veroorzaken.
Nullish Coalescing (??)
De nullish coalescing operator (??), ook geïntroduceerd in ES2020, biedt een manier om een standaardwaarde toe te wijzen aan een variabele als de variabele null of undefined is. Dit verschilt van de logische OR-operator (||), die een standaardwaarde toewijst als de variabele een 'falsy' waarde heeft (zoals 0, '', false).
?? is preciezer omdat het alleen reageert op null en undefined. Dit is handig wanneer 0 of een lege string '' geldige waarden zijn die u niet wilt vervangen door een standaardwaarde. Bijvoorbeeld bij het instellen van configuraties of gebruikersvoorkeuren.
const gebruikersInstellingen = {
thema: 'donker',
notificaties: true,
aantalItems: 0, // 0 is een geldige waarde
taal: '' // Lege string is een geldige waarde
};
const standaardInstellingen = {
thema: 'licht',
notificaties: false,
aantalItems: 10,
taal: 'nl'
};
// Gebruik van || (logische OR)
// Probleem: 0, '', false worden als 'falsy' behandeld en vervangen door standaardwaarde
const themaOR = gebruikersInstellingen.thema || standaardInstellingen.thema;
console.log('Thema (OR):', themaOR); // donker
const aantalItemsOR = gebruikersInstellingen.aantalItems || standaardInstellingen.aantalItems;
console.log('Aantal items (OR):', aantalItemsOR); // 10 (fout, wilde 0 behouden)
const taalOR = gebruikersInstellingen.taal || standaardInstellingen.taal;
console.log('Taal (OR):', taalOR); // nl (fout, wilde lege string behouden)
// Gebruik van ?? (Nullish Coalescing)
// Alleen null of undefined worden vervangen door standaardwaarde
const themaNC = gebruikersInstellingen.thema ?? standaardInstellingen.thema;
console.log('Thema (NC):', themaNC); // donker
const aantalItemsNC = gebruikersInstellingen.aantalItems ?? standaardInstellingen.aantalItems;
console.log('Aantal items (NC):', aantalItemsNC); // 0 (correct!)
const taalNC = gebruikersInstellingen.taal ?? standaardInstellingen.taal;
console.log('Taal (NC):', taalNC); // '' (correct!)
const nietBestaandItem = gebruikersInstellingen.nietBestaand ?? 'standaard';
console.log('Niet bestaand item (NC):', nietBestaandItem); // standaardCODE-UITLEG: De nullish coalescing operator (??) wijst een standaardwaarde toe alleen als de variabele null of undefined is. Dit is preciezer dan de logische OR-operator (||), die ook reageert op andere 'falsy' waarden zoals 0, '' en false.
BigInt
BigInt, geïntroduceerd in ES2020, is een nieuw primitief datatype in JavaScript dat getallen kan weergeven die groter zijn dan de limiet van het standaard Number-type (2^53 - 1, of Number.MAX_SAFE_INTEGER). Dit is essentieel voor toepassingen die zeer grote gehele getallen vereisen, zoals cryptografie, financiële berekeningen of het werken met database-ID's die buiten het 'veilige' bereik vallen.
BigInt-waarden worden gecreëerd door een n achter een geheel getal te plaatsen of door de BigInt()-constructor te gebruiken. Het is belangrijk op te merken dat BigInt en Number niet direct met elkaar gemengd kunnen worden in wiskundige operaties zonder expliciete typeconversie.
// Maximale veilige integer voor Number
const maxSafe = Number.MAX_SAFE_INTEGER;
console.log('Max safe integer:', maxSafe); // 9007199254740991// Optellen boven de veilige limiet met Number kan leiden tot onnauwkeurigheden
console.log('Max safe + 1:', maxSafe + 1); // 9007199254740992
console.log('Max safe + 2:', maxSafe + 2); // 9007199254740992 (fout, zou 9007199254740993 moeten zijn)
// BigInt gebruiken
const bigIntNum = 9007199254740991n; // 'n' aan het einde maakt het een BigInt
console.log('BigInt:', bigIntNum);
console.log('BigInt + 1:', bigIntNum + 1n); // 9007199254740992n (correct)
console.log('BigInt + 2:', bigIntNum + 2n); // 9007199254740993n (correct)
// BigInt constructor
const anotherBigInt = BigInt('123456