Start · Sprachen · JavaScript · Referenz · Intl.ListFormat

Intl.ListFormat

Klasse

Formatiert Arrays und andere Iterables aus Strings als lokalisierte Aufzählung, z. B. „A, B und C“ auf Deutsch oder „A, B, or C“ auf Englisch.

seit JavaScript ES2021 (ECMA-402 8. Ausgabe) · Baseline seit April Kategorie: core

Signatur

class Intl.ListFormat

Beschreibung

Intl.ListFormat gehört zur Internationalisierungs-API von ECMAScript. Die Klasse macht aus einer Liste von Zeichenketten eine Aufzählung, die in der gewählten Sprache natürlich klingt. Kommas, Konjunktionen („und“) und Disjunktionen („oder“) setzt sie selbst. Eigene Lösungen wie arr.slice(0, -1).join(", ") + " und " + arr.at(-1) brauchst du damit nicht mehr. Solche Lösungen scheitern ohnehin an Sprachen mit anderen Regeln, etwa am Oxford-Komma im Englischen („A, B, and C“), an Sprachen ohne Leerzeichen (Japanisch, Chinesisch) oder an Konjunktionen, die sich nach dem folgenden Wort richten (spanisch „y“ wird vor „i-“-Lauten zu „e“).

Ein Objekt entsteht mit new Intl.ListFormat(locales, options). Die Option type legt die Art der Liste fest:

  • "conjunction" (Standard): „und“-Listen, z. B. „Äpfel, Birnen und Kirschen“
  • "disjunction": „oder“-Listen, z. B. „Bahn, Bus oder Rad“
  • "unit": Listen von Maßangaben, z. B. „3 hours, 15 minutes“

Mit style ("long", "short", "narrow") steuerst du, wie knapp das Ergebnis ausfällt. Die Instanzmethoden:

  • format(list) gibt die fertige Zeichenkette zurück.
  • formatToParts(list) gibt ein Array aus { type, value }-Objekten zurück. type ist dabei "element" oder "literal". So kannst du einzelne Einträge gezielt hervorheben.
  • resolvedOptions() zeigt die tatsächlich verwendete Locale und die aufgelösten Optionen.

Die statische Methode Intl.ListFormat.supportedLocalesOf() prüft, welche der angefragten Locales die Laufzeitumgebung unterstützt, ohne auf eine Standard-Locale auszuweichen. Wenn du viele Listen formatierst, erzeuge die Instanz einmal und nutze sie wieder. Der Konstruktor lädt Locale-Daten und ist deutlich teurer als ein einzelner format()-Aufruf.

Parameter

Name Typ Default Beschreibung
$locales string | string[] | Intl.Locale | undefined Standard-Locale der Laufzeitumgebung BCP-47-Sprach-Tag wie "de-DE" oder "en-GB", ein Array solcher Tags in Prioritätsreihenfolge oder ein Intl.Locale-Objekt.
$options.localeMatcher "lookup" | "best fit" "best fit" Algorithmus für die Auswahl der Locale.
$options.type "conjunction" | "disjunction" | "unit" "conjunction" Art der Liste: „und“-Liste, „oder“-Liste oder Liste von Maßangaben.
$options.style "long" | "short" | "narrow" "long" Länge der Ausgabe. Bei "narrow" fallen Konjunktionen je nach Sprache und Typ ganz weg oder werden durch Leerzeichen ersetzt.

Rückgabewert

Typ
Intl.ListFormat
Beschreibung
Eine neue Instanz mit den Methoden format(), formatToParts() und resolvedOptions().

Beispiele

„und“- und „oder“-Listen auf Deutsch und Englisch

const zutaten = ['Mehl', 'Zucker', 'Eier'];

const deUnd = new Intl.ListFormat('de', { type: 'conjunction' });
const deOder = new Intl.ListFormat('de', { type: 'disjunction' });
const enUnd = new Intl.ListFormat('en-US', { style: 'long', type: 'conjunction' });

console.log(deUnd.format(zutaten));
console.log(deOder.format(zutaten));
console.log(enUnd.format(['flour', 'sugar', 'eggs']));

// Randfälle
console.log(deUnd.format(['Mehl']));
console.log(JSON.stringify(deUnd.format([])));
Mehl, Zucker und Eier Mehl, Zucker oder Eier flour, sugar, and eggs Mehl ""

Einträge mit formatToParts() hervorheben

const escapeHtml = (s) =>
  s.replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));

const lf = new Intl.ListFormat('de', { type: 'conjunction' });
const namen = ['Anna', 'Ben', 'Clara'];

const html = lf
  .formatToParts(namen)
  .map(({ type, value }) =>
    type === 'element' ? `<strong>${escapeHtml(value)}</strong>` : escapeHtml(value)
  )
  .join('');

console.log(lf.formatToParts(namen));
console.log(html);
[ { type: 'element', value: 'Anna' }, { type: 'literal', value: ', ' }, { type: 'element', value: 'Ben' }, { type: 'literal', value: ' und ' }, { type: 'element', value: 'Clara' } ] <strong>Anna</strong>, <strong>Ben</strong> und <strong>Clara</strong>

Zeitdauern als Einheiten-Liste mit Intl.NumberFormat

const formatDauer = (stunden, minuten, locale = 'en', style = 'long') => {
  const h = new Intl.NumberFormat(locale, { style: 'unit', unit: 'hour', unitDisplay: style });
  const m = new Intl.NumberFormat(locale, { style: 'unit', unit: 'minute', unitDisplay: style });
  const lf = new Intl.ListFormat(locale, { type: 'unit', style });
  return lf.format([h.format(stunden), m.format(minuten)]);
};

console.log(formatDauer(3, 15));
console.log(formatDauer(3, 15, 'en', 'narrow'));
3 hours, 15 minutes 3h 15m

Unterstützung prüfen und aufgelöste Optionen lesen

console.log(Intl.ListFormat.supportedLocalesOf(['de-CH', 'tlh', 'ja']));

const lf = new Intl.ListFormat(['tlh', 'de-AT'], { style: 'short' });
console.log(lf.resolvedOptions());

// Iterables funktionieren auch, etwa ein Set
const tags = new Set(['JavaScript', 'CSS', 'HTML']);
console.log(lf.format(tags));
[ 'de-CH', 'ja' ] { locale: 'de-AT', type: 'conjunction', style: 'short' } JavaScript, CSS und HTML

// Wichtig · Fallstricke

Browser-Kompatibilität: Intl.ListFormat ist seit Chrome 72, Firefox 78, Safari 14.1 und Edge 79 verfügbar. In älteren Umgebungen (z. B. IE 11) wird ein Polyfill benötigt (FormatJS). Node.js unterstützt Intl.ListFormat ab v12 (mit full-icu).

Leere Listen: format([]) gibt einen leeren String ("") zurück – dies sollte in der Anzeige-Logik berücksichtigt werden, da ein leeres Label für Nutzer verwirrend sein kann.

Performance: Das Erstellen von Intl.ListFormat-Instanzen ist teuer. Bei wiederholter Verwendung desselben Locale/Optionen-Paares sollte die Instanz wiederverwendet (gecacht) werden, statt sie in jedem Render-Zyklus neu zu erzeugen.

Typen im Detail: type: "unit" erzeugt in einigen Locales eine Liste ohne explizite Konjunktion (z. B. Englisch: "3 hours, 15 minutes, 30 seconds"), was sich von conjunction unterscheiden kann. Das genaue Trennzeichen ist locale-abhängig und darf nicht hartcodiert werden.