Start · Sprachen · JavaScript · Referenz · Intl.NumberFormat.prototype.formatToParts()

Intl.NumberFormat.prototype.formatToParts()

Methode

Formatiert eine Zahl sprachabhängig und gibt statt eines Strings ein Array von <code>{ type, value }</code>-Objekten zurück, die jeden Teil der formatierten Ausgabe beschreiben.

seit JavaScript ECMA-402 (ES2018); Baseline: alle modernen Browser Kategorie: method-property

Signatur

Intl.NumberFormat.prototype.formatToParts(number)

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

Typ
Array<{ type: string, value: string }>
Beschreibung
Ein Array von Objekten, deren 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));
[ { type: "integer", value: "1" }, { type: "group", value: "." }, { type: "integer", value: "234" }, { type: "decimal", value: "," }, { type: "fraction", value: "50" }, { type: "literal", value: " " }, // U+00A0 (geschütztes Leerzeichen) { type: "currency", value: "€" } ]

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));
19,<sup>99</sup> <small class="currency">€</small>

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"));
{ decimal: ",", group: "." } { decimal: ".", group: "," } { decimal: ".", group: "’" }

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(" | "));
minusSign="-" | integer="1" | decimal="," | fraction="5" | literal=" " | compact="Mio."

// Wichtig · Fallstricke

  • Geschützte Leerzeichen: Zwischen Betrag und Währung bzw. in literal-Teilen stehen häufig U+00A0 oder U+202F statt normaler Leerzeichen. Vergleiche wie value === " " 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 type filtern.
  • Anders als format (ein gebundener Getter) ist formatToParts eine normale Methode. Wer sie als Callback übergibt, z. B. arr.map(fmt.formatToParts), verliert this und löst einen TypeError aus. Stattdessen eine Pfeilfunktion verwenden.
  • XSS: Wer die Teile wie im Beispiel zu HTML zusammensetzt, sollte das nur mit Zahlen tun, die von Intl erzeugt wurden. Eigene Texte nicht ungeprüft über innerHTML einfügen.
  • Der Typ approximatelySign und die exakte Behandlung von Strings kamen erst mit Intl.NumberFormat v3 (ES2023) hinzu. Ältere Engines kennen sie nicht. Für Zahlenbereiche gibt es formatRangeToParts(), das zusätzlich ein Feld source liefert.
  • Bei vielen Aufrufen die Intl.NumberFormat-Instanz wiederverwenden, denn ihre Erzeugung kostet vergleichsweise viel Rechenzeit.