javascript 34 lines · 8 steps

Caching Intl.NumberFormat for currency formatting

A memoized factory reuses expensive Intl.NumberFormat instances to format currency, cents, and ranges.

Explained by highlit
1const formatters = new Map();
2 
3function getFormatter(locale, currency) {
4 const key = `${locale}:${currency}`;
5 let formatter = formatters.get(key);
6 
7 if (!formatter) {
8 formatter = new Intl.NumberFormat(locale, {
9 style: 'currency',
10 currency,
11 currencyDisplay: 'symbol',
12 });
13 formatters.set(key, formatter);
14 }
15 
16 return formatter;
17}
18 
19export function formatCurrency(amount, { locale = 'en-US', currency = 'USD' } = {}) {
20 if (amount == null || Number.isNaN(amount)) {
21 return '';
22 }
23 
24 return getFormatter(locale, currency).format(amount);
25}
26 
27export function formatFromCents(cents, options = {}) {
28 return formatCurrency(cents / 100, options);
29}
30 
31export function formatRange(min, max, options = {}) {
32 const formatter = getFormatter(options.locale ?? 'en-US', options.currency ?? 'USD');
33 return formatter.formatRange(min, max);
34}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Constructing Intl formatters is costly, so caching them by their configuration avoids repeated setup.
  2. 2A composite string key lets a single Map memoize across multiple independent parameters.
  3. 3Sharing one cached formatter behind several public helpers keeps behavior consistent and cheap.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Caching Intl.NumberFormat for currency formatting — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code