Signatur
Beschreibung
formatToParts() liefert dieselbe Formatierung wie Intl.NumberFormat.prototype.format(), zerlegt das Ergebnis aber in einzelne, typisierte Bestandteile. Jedes Element des Arrays ist ein Objekt mit type (z. B. "integer", "group", "decimal", "fraction", "currency") und value (dem tatsächlichen Text). Fügt man alle value-Werte zusammen, erhält man exakt den String, den format() liefern würde.
Das ist nützlich, wenn einzelne Teile einer Zahl unterschiedlich dargestellt werden sollen, etwa ein kleineres Währungssymbol, hervorgehobene Nachkommastellen oder ein farbiges Vorzeichen. Ohne formatToParts() müsste man den formatierten String mit fehleranfälligen regulären Ausdrücken zerlegen, die bei jeder Sprache anders aussehen.
Ein zweiter typischer Einsatz ist das Ermitteln lokaler Trennzeichen: Aus den Teilen mit type: "decimal" bzw. type: "group" kann man das Dezimal- und Tausendertrennzeichen einer Sprache ablesen, etwa um Benutzereingaben zu parsen.
Mögliche Werte für type sind unter anderem: integer, group, decimal, fraction, plusSign, minusSign, percentSign, currency, unit, compact, exponentSeparator, exponentMinusSign, exponentInteger, nan, infinity, approximatelySign, literal und unknown.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $number | number | bigint | string | undefined | Die zu formatierende Zahl. Strings werden seit Intl.NumberFormat v3 (ES2023) als exakte Dezimalzahlen interpretiert, ohne Umweg über Number. Fehlt der Wert, wird undefined formatiert, was NaN ergibt. |
Rückgabewert
value-Werte aneinandergereiht den String von format() ergeben. type gibt die Art des jeweiligen Teils an.Beispiele
Währungsbetrag in seine Teile zerlegen
const eur = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
});
console.log(eur.formatToParts(1234.5));
Währungssymbol und Nachkommastellen gesondert auszeichnen
const fmt = new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR",
});
const toHtml = (amount) =>
fmt
.formatToParts(amount)
.map(({ type, value }) => {
switch (type) {
case "currency":
return `<small class="currency">${value}</small>`;
case "fraction":
return `<sup>${value}</sup>`;
default:
return value;
}
})
.join("");
document.querySelector("#preis").innerHTML = toHtml(19.99);
console.log(toHtml(19.99));
Dezimal- und Tausendertrennzeichen einer Sprache ermitteln
const getSeparators = (locale) => {
const parts = new Intl.NumberFormat(locale).formatToParts(12345.6);
return {
decimal: parts.find((p) => p.type === "decimal")?.value,
group: parts.find((p) => p.type === "group")?.value,
};
};
console.log(getSeparators("de-DE"));
console.log(getSeparators("en-US"));
console.log(getSeparators("de-CH"));
Kompakte Notation und Vorzeichen
const compact = new Intl.NumberFormat("de-DE", {
notation: "compact",
signDisplay: "always",
});
const parts = compact.formatToParts(-1500000);
console.log(parts.map((p) => `${p.type}=${JSON.stringify(p.value)}`).join(" | "));
// Wichtig · Fallstricke
- Geschützte Leerzeichen: Zwischen Betrag und Währung bzw. in
literal-Teilen stehen häufigU+00A0oderU+202Fstatt normaler Leerzeichen. Vergleiche wievalue === " "schlagen deshalb fehl. - Ausgabe nicht fest verdrahten: Reihenfolge, Symbole und Trennzeichen hängen von Sprache und ICU-/CLDR-Version der Laufzeitumgebung ab und können sich zwischen Browser-Versionen ändern. Nicht auf feste Indizes zugreifen, sondern immer über
typefiltern. - Anders als
format(ein gebundener Getter) istformatToPartseine normale Methode. Wer sie als Callback übergibt, z. B.arr.map(fmt.formatToParts), verliertthisund löst einenTypeErroraus. Stattdessen eine Pfeilfunktion verwenden. - XSS: Wer die Teile wie im Beispiel zu HTML zusammensetzt, sollte das nur mit Zahlen tun, die von
Intlerzeugt wurden. Eigene Texte nicht ungeprüft überinnerHTMLeinfügen. - Der Typ
approximatelySignund die exakte Behandlung von Strings kamen erst mit Intl.NumberFormat v3 (ES2023) hinzu. Ältere Engines kennen sie nicht. Für Zahlenbereiche gibt esformatRangeToParts(), das zusätzlich ein Feldsourceliefert. - Bei vielen Aufrufen die
Intl.NumberFormat-Instanz wiederverwenden, denn ihre Erzeugung kostet vergleichsweise viel Rechenzeit.