
Gebruik voor het weergeven van een getal Intl.NumberFormat of de kortere vorm toLocaleString(): (1234.5).toLocaleString('fr-FR', { minimumFractionDigits: 2 }) geeft “1 234,50”, en de optie style: 'currency' voegt de valuta toe. Om af te ronden zonder weer te geven, Math.round(n * 100) / 100, toFixed(2) rondt ook af maar geeft een string terug.
Een getal wordt berekend als Number en weergegeven als string: “1 234,50 €”, “25,6 %”, “1,4 k weergaven”. Daartussen moet je afronden, een duizendtalscheiding plaatsen, de komma of de punt kiezen. JavaScript doet dit allemaal zonder library, dankzij toFixed, toLocaleString en vooral Intl.NumberFormat. Alle onderstaande uitvoer is uitgevoerd onder Node.js 22.
Een getal afronden
Math.round, Math.floor, Math.ceil, Math.trunc
Math.round(2.5); // 3 : naar het dichtstbijzijnde, .5 rondt naar boven af
Math.round(-2.5); // -2 : richting +Infinity, niet “weg van nul”
Math.floor(4.7); // 4 : naar beneden
Math.floor(-4.2); // -5
Math.ceil(4.2); // 5 : naar boven
Math.trunc(-4.7); // -4 : snijdt het decimale deel af, ongeacht het tekenDeze functies kennen alleen het gehele getal. Om op twee decimalen af te ronden, vermenigvuldig je, rond je af, en deel je:
Math.round(1.345 * 100) / 100; // 1.35
Math.round(1.005 * 100) / 100; // 1 : verwacht 1.01, zie hieronderDe valkuil van binaire decimalen
1.005 bestaat niet in binaire vorm: het opgeslagen getal is 1.00499999… en wordt dus afgerond tot 1.00. Dit is geen bug van JavaScript maar van het IEEE 754-formaat, gemeenschappelijk voor alle talen. Twee oplossingen:
// 1. De representatiefout corrigeren voor het afronden
Math.round((1.005 + Number.EPSILON) * 100) / 100; // 1.01
// 2. Nooit decimalen opslaan: prijzen in hele centen
const prixCentimes = 1005;
(prixCentimes / 100).toFixed(2); // '10.05'De tweede is de regel voor alles wat met geld te maken heeft: hele centen optellen geeft nooit 0.30000000000000004.
toFixed() : afronden om weer te geven
(1234.5678).toFixed(2); // '1234.57'
(2.5).toFixed(0); // '3'
(1.005).toFixed(2); // '1.00' : dezelfde binaire valkuil als Math.round
(0.1 + 0.2).toFixed(2); // '0.30' : daar dient het nu net voor
typeof (1.5).toFixed(2); // 'string'
(1.5).toFixed(2) + 1; // '1.501' : concatenatie, geen optellingtoFixed geeft een string terug. Dat is perfect voor de weergave, gevaarlijk voor de berekening: converteer met Number() als je de waarde opnieuw moet gebruiken. En zijn decimaalteken is altijd een punt, voor de Franse komma gebruik je toLocaleString.
Duizendtalscheiding en Frans formaat: toLocaleString()
const n = 1234567.891;
n.toLocaleString('fr-FR'); // '1 234 567,891'
n.toLocaleString('en-US'); // '1,234,567.891'
n.toLocaleString('de-DE'); // '1.234.567,891'
(1234.5).toLocaleString('fr-FR', { minimumFractionDigits: 2 }); // '1 234,50'
(3.14159).toLocaleString('fr-FR', { maximumFractionDigits: 2 }); // '3,14'Eén methode, drie nationale conventies, geen enkele regel formatteercode. Twee verduidelijkingen:
- Het Franse duizendtalscheidingsteken is geen gewone spatie maar een smalle onderbrekingsspatie (U+202F). Ze voorkomt dat “1 234” aan het einde van een regel wordt afgebroken. Moet je ze verwijderen, filter dan met
/\s/g, niet met' '. - Zonder taalargument gebruikt
toLocaleString()die van de browser of het systeem. Voor een stabiel resultaat geef je altijd'fr-FR'op.
Intl.NumberFormat: valuta, percentage, eenheden
toLocaleString is een kortere vorm van Intl.NumberFormat. Het volledige object maak je één keer aan en hergebruik je, wat van belang is zodra je een lijst of tabel formatteert.
const euros = new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' });
euros.format(1234.5); // '1 234,50 €'
const dollars = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
dollars.format(1234.5); // '$1,234.50'
const pourcent = new Intl.NumberFormat('fr-FR', { style: 'percent', maximumFractionDigits: 1 });
pourcent.format(0.256); // '25,6 %' : de waarde is een ratio, 0.256 en niet 25.6
const km = new Intl.NumberFormat('fr-FR', { style: 'unit', unit: 'kilometer' });
km.format(12.5); // '12,5 km'
const go = new Intl.NumberFormat('fr-FR', { style: 'unit', unit: 'gigabyte', maximumFractionDigits: 2 });
go.format(2.35); // '2,35 Go'De valutaformatter plaatst het symbool op de juiste plek volgens de taal (na het bedrag in het Frans, ervoor in het Engels), kiest het aantal decimalen van de munt en voegt de onderbrekingsspatie in. Stuk voor stuk regels die je niet meer zelf hoeft te coderen.
Compacte notatie: 1,4 k en 1 M
“1 400 weergaven” tonen als “1,4 k” of “1 000 000” als “1 M” is een veelvoorkomende behoefte. De optie notation: 'compact' doet dat, in de gewenste taal.
const compact = new Intl.NumberFormat('fr-FR', { notation: 'compact' });
compact.format(1400); // '1,4 k'
compact.format(1000000); // '1 M'
new Intl.NumberFormat('en-US', { notation: 'compact' }).format(23000); // '23K'
new Intl.NumberFormat('en-US', { notation: 'compact', maximumFractionDigits: 3 }).format(1230974); // '1.231M'
new Intl.NumberFormat('fr-FR', { notation: 'compact', compactDisplay: 'long' }).format(2500000); // '2,5 millions'Andere nuttige opties:
new Intl.NumberFormat('fr-FR', { minimumIntegerDigits: 2 }).format(7); // '07'
new Intl.NumberFormat('fr-FR', { useGrouping: false }).format(1234567); // '1234567'
new Intl.NumberFormat('fr-FR', { signDisplay: 'always' }).format(12); // '+12'
new Intl.NumberFormat('en-US', { notation: 'scientific' }).format(676565765722); // '6.766E11'
new Intl.NumberFormat('fr-FR', { maximumFractionDigits: 2, roundingMode: 'halfExpand' }).format(1.005); // '1,01'De laatste regel verdient een woordje uitleg: Intl.NumberFormat rondt af op basis van de decimale representatie van het getal, niet van de binaire benadering ervan. 1.005 wordt terecht “1,01”, waar toFixed “1.00” gaf. Dat is nog een reden om met Intl te formatteren in plaats van met de hand.
Beginnullen en andere talstelsels
String(7).padStart(2, '0'); // '07' : uren, minuten, factuurnummers
String(7).padStart(3, '0'); // '007'
(255).toString(16); // 'ff' : hexadecimaal, voor een CSS-kleur
(255).toString(2); // '11111111' : binair
(123.456).toPrecision(4); // '123.5' : totaal aantal significante cijfers
(1234.5678).toExponential(2); // '1.23e+3'Twee gedragingen van toString() om te kennen: boven 1021 en onder 10−6 schakelt JavaScript over op wetenschappelijke notatie ((1e21).toString() geeft '1e+21', (0.0000001).toString() geeft '1e-7'). toFixed of Intl.NumberFormat met notation: 'standard' behouden de uitgeschreven vorm.
De omgekeerde bewerking
Een geformatteerde string laat zich niet zomaar terugzetten: Number('1 234,50') is NaN. Je moet de spaties verwijderen en de komma vervangen voor je converteert. De volledige aanpak staat in String naar getal omzetten in JavaScript.
En Numeral.js?
De eerste versie van dit artikel besprak Numeral.js, een library met een compact formaat: numeral(50000).format('0,0') voor “50,000”, '0a' voor “23k”, '0.00b' voor “2.35GB”, '0o' voor “23rd”. Ze wordt nog in veel projecten gebruikt en de syntax is aangenaam.
import numeral from 'numeral';
numeral(50000).format('0,0'); // 50,000
numeral(23000).format('0a'); // 23k
numeral(2348895676).format('0.00b'); // 2.35GBMaar de laatste versie, 2.0.6, dateert van maart 2017 en het project wordt niet meer onderhouden: de locales liggen vast en het Franse scheidingsteken is niet de verwachte smalle spatie. Voor een nieuw project dekt Intl.NumberFormat dezelfde behoeften (duizendtallen, compact, valuta, percentage) zonder dependency, met de echte conventies van elke taal en geen enkel gewicht in de bundle. Behoud Numeral waar het al zit, voeg het niet meer toe.
Samenvatting
| Behoefte | Tool | Voorbeeld |
|---|---|---|
| Afronden om te berekenen | Math.round(n * 100) / 100 of hele centen | 1.35 |
| Afronden om weer te geven, decimale punt | toFixed(2) | '1234.57' |
| Frans formaat, duizendtallen en komma | toLocaleString('fr-FR') | '1 234 567,891' |
| Valuta, percentage, eenheid | Intl.NumberFormat + style | '1 234,50 €' |
| 1,4 k / 1 M | notation: 'compact' | '1,4 k' |
| Beginnullen | padStart(2, '0') | '07' |
Veelgemaakte fouten
(1.5).toFixed(2) + 1 geeft “1.501”: toFixed geeft een string terug, de optelling plakt aan elkaar. Converteer met Number() als je opnieuw moet rekenen.(1.005).toFixed(2) is “1.00” omdat 1.005 binair wordt opgeslagen als 1.00499999… Werk voor een financiële afronding met hele centen.toLocaleString('fr-FR') vervangen door een gewone spatie Het Franse duizendtalscheidingsteken is een smalle onderbrekingsspatie (U+202F). Een replace(' ', '') verwijdert ze niet, gebruik /\s/g.format() aan op elke waarde.

