Start · Sprachen · JavaScript · Referenz · Template-Literale (Template-Zeichenketten)

Template-Literale (Template-Zeichenketten)

Keyword

Template-Literale sind mit Backticks begrenzte Zeichenketten. Sie können mehrzeilig sein, Ausdrücke per <code>${…}</code> einbetten und über Tag-Funktionen weiterverarbeitet werden.

seit JavaScript ES2015 Kategorie: syntax

Signatur

`Text ${ausdruck} Text` | tag`Text ${ausdruck} Text`

Beschreibung

Ein Template-Literal steht zwischen Backticks (`…`) statt zwischen einfachen oder doppelten Anführungszeichen. Innerhalb davon werden Platzhalter der Form ${ausdruck} ausgewertet. Das Ergebnis wird in eine Zeichenkette umgewandelt und an dieser Stelle eingefügt. So spart man sich die umständliche Verkettung mit +, und Zeilenumbrüche im Quelltext bleiben in der Zeichenkette unverändert erhalten.

Steht direkt vor dem Literal ein Funktionsausdruck, spricht man von einem getaggten Template (tag`…`). Die Tag-Funktion bekommt als erstes Argument ein Array mit den festen Textteilen (strings). Danach folgen die ausgewerteten Platzhalter als weitere Argumente. Sie darf einen beliebigen Wert zurückgeben, nicht nur eine Zeichenkette. Das nutzen zum Beispiel Bibliotheken für HTML-Escaping, SQL-Abfragen, CSS-in-JS (styled-components) oder GraphQL (gql).

Das Array strings hat die zusätzliche Eigenschaft raw. Sie enthält die Textteile unverarbeitet, also ohne ausgewertete Escape-Sequenzen. Die eingebaute Tag-Funktion String.raw macht sich das zunutze, etwa für Windows-Pfade oder reguläre Ausdrücke.

Einsatzgebiete: lesbare Formatierung von Meldungen, mehrzeilige Textbausteine (HTML-Schnipsel, SQL, Hilfetexte) und eigene kleine Sprachen (DSLs) über Tag-Funktionen.

Parameter

Name Typ Default Beschreibung
$ausdruck any Beliebiger JavaScript-Ausdruck innerhalb von ${…}. Ohne Tag wird das Ergebnis wie bei String(wert) in eine Zeichenkette umgewandelt; Symbol-Werte lösen einen TypeError aus.
$tag Function Optionale Tag-Funktion direkt vor dem Literal. Sie wird als tag(strings, ...werte) aufgerufen.
$strings ReadonlyArray<string> & { raw: ReadonlyArray<string> } Nur bei getaggten Templates: eingefrorenes Array mit den festen Textteilen. Es hat immer ein Element mehr als es Platzhalter gibt. strings.raw enthält die unverarbeiteten Textteile.
$...werte any[] Nur bei getaggten Templates: die ausgewerteten Platzhalter in der Reihenfolge ihres Auftretens. Sie werden nicht vorher in Zeichenketten umgewandelt.

Rückgabewert

Typ
string | any
Beschreibung
Ohne Tag: eine neue Zeichenkette (string). Mit Tag: der Rückgabewert der Tag-Funktion, der einen beliebigen Typ haben kann.

Beispiele

Interpolation statt Verkettung

const produkt = 'Tastatur';
const preis = 49.9;
const menge = 3;

// Früher: 'Summe für ' + menge + 'x ' + produkt + ': ' + ...
const text = `Summe für ${menge}x ${produkt}: ${(preis * menge).toFixed(2)} €`;
console.log(text);
Summe für 3x Tastatur: 149.70 €

Mehrzeiliges HTML aus Daten erzeugen

const nutzer = [
  { name: 'Anna', rolle: 'Admin' },
  { name: 'Ben', rolle: 'Redakteur' }
];

const liste = `<ul>
${nutzer.map(({ name, rolle }) => `  <li>${name} (${rolle})</li>`).join('\n')}
</ul>`;

console.log(liste);
<ul> <li>Anna (Admin)</li> <li>Ben (Redakteur)</li> </ul>

Getaggtes Template zum HTML-Escaping

const escapeHtml = (wert) => String(wert)
  .replaceAll('&', '&amp;')
  .replaceAll('<', '&lt;')
  .replaceAll('>', '&gt;')
  .replaceAll('"', '&quot;')
  .replaceAll("'", '&#39;');

// Tag-Funktion: feste Textteile bleiben, Werte werden escaped
const html = (strings, ...werte) =>
  strings.reduce((erg, teil, i) =>
    erg + teil + (i < werte.length ? escapeHtml(werte[i]) : ''), '');

const eingabe = '<img src=x onerror=alert(1)>';
console.log(html`<p>Kommentar: ${eingabe}</p>`);
<p>Kommentar: &lt;img src=x onerror=alert(1)&gt;</p>

String.raw und strings.raw

// Backslashes bleiben unverändert erhalten
const pfad = String.raw`C:\Users\neu\temp`;
console.log(pfad);

const zeige = (strings) => [strings[0], strings.raw[0]];
console.log(zeige`Zeile\nUmbruch`);
C:\Users\neu\temp [ 'Zeile\nUmbruch', 'Zeile\\nUmbruch' ]

// Wichtig · Fallstricke

  • XSS-Gefahr: Ein Template-Literal escaped nichts. Die Kombination element.innerHTML = `…${nutzereingabe}…` öffnet Cross-Site-Scripting die Tür. Verwende textContent, eine escapende Tag-Funktion oder eine Bibliothek wie DOMPurify. Das gilt genauso für SQL: Baue Abfragen nie per Interpolation zusammen, sondern nutze parametrisierte Abfragen oder SQL-Tag-Funktionen, die Platzhalter erzeugen.
  • Leerraum: Einrückung und Zeilenumbrüche im Quelltext landen vollständig in der Zeichenkette. Das betrifft auch den Umbruch direkt nach dem öffnenden Backtick.
  • Escaping im Literal: Ein Backtick wird als \` geschrieben, ein wörtliches ${ als \${.
  • Umwandlung in Zeichenketten: Objekte erscheinen als [object Object], null und undefined als "null" bzw. "undefined". Symbol-Werte werfen einen TypeError. Die Umwandlung nutzt ToString mit Vorrang für toString; das kann bei Objekten mit valueOf ein anderes Ergebnis liefern als '' + obj.
  • Bei getaggten Templates ist das strings-Array pro Aufrufstelle identisch und eingefroren. Es eignet sich deshalb als Cache-Schlüssel, wie es etwa lit-html macht.
  • Seit ES2018 sind ungültige Escape-Sequenzen wie \unicode in getaggten Templates erlaubt; strings[i] ist dann undefined, nur raw ist gefüllt. In normalen Template-Literalen bleiben sie ein SyntaxError.
  • Kompatibilität: Alle modernen Browser und Node.js 4+ unterstützen Template-Literale. Der Internet Explorer kann sie nicht; dort ist Transpilierung (z. B. mit Babel) nötig.