Literal mit ES6-Vorlagenstrings abrufen

Osmani
Addy Osmani

Strings in JavaScript waren in der Vergangenheit nur eingeschränkt verfügbar, da nicht die Funktionen fehlen, die man von Sprachen wie Python oder Ruby erwarten würde. ES6-Vorlagenstrings (verfügbar in Chrome 41 und höher), ändern das grundlegend. Sie führen eine Möglichkeit ein, Zeichenfolgen mit domainspezifischen Sprachen (DSLs) zu definieren. Dies hat folgende Vorteile:

  • String interpolation
  • Eingebettete Ausdrücke
  • Mehrzeilige Strings ohne Hacks
  • Stringformatierung
  • String-Tagging für sicheres HTML-Escaping, Lokalisierung und vieles mehr

Anstatt eine weitere Funktion in Zeichenfolgen zu stecken, wie wir sie heute kennen, bieten Vorlagen-Strings eine völlig andere Art der Lösung dieser Probleme.

Syntax

Vorlagenstrings verwenden Graviszeichen (``) anstelle der einfachen oder doppelten Anführungszeichen, die wir von regulären Strings kennen. Eine Vorlagenzeichenfolge könnte somit so geschrieben werden:

var greeting = `Yo World!`;

Bisher haben uns Vorlagenstrings nicht mehr als normale Strings gegeben. Lassen Sie uns das ändern.

Stringersetzung

Einer der ersten großen Vorteile ist die Stringersetzung. Die Substitution ermöglicht es uns, jeden gültigen JavaScript-Ausdruck (z. B. das Hinzufügen von Variablen) zu verwenden. In einem Vorlagenliteral wird dann das Ergebnis als Teil desselben Strings ausgegeben.

Vorlagenstrings können Platzhalter für die Stringersetzung mithilfe der Syntax ${ } enthalten, wie unten gezeigt:

// Simple string substitution
var name = "Brendan";
console.log(`Yo, ${name}!`);

// => "Yo, Brendan!"

Da alle String-Ersetzungen in Vorlagen-Strings JavaScript-Ausdrücke sind, können wir viel mehr ersetzen als Variablennamen. Im folgenden Beispiel können wir die Ausdrucksinterpolation verwenden, um einige lesbare Inline-Berechnungen einzubetten:

var a = 10;
var b = 10;
console.log(`JavaScript first appeared ${a+b} years ago. Wow!`);

//=> JavaScript first appeared 20 years ago. Wow!

console.log(`The number of JS MVC frameworks is ${2 * (a + b)} and not ${10 * (a + b)}.`);
//=> The number of JS frameworks is 40 and not 200.

Sie sind auch sehr nützlich für Funktionen innerhalb von Ausdrücken:

function fn() { return "I am a result. Rarr"; }
console.log(`foo ${fn()} bar`);
//=> foo I am a result. Rarr bar.

Der ${} funktioniert mit jeder Art von Ausdruck, einschließlich Mitgliedsausdrücken und Methodenaufrufen:

var user = {name: 'Caitlin Potter'};
console.log(`Thanks for getting this into V8, ${user.name.toUpperCase()}.`);

// => "Thanks for getting this into V8, CAITLIN POTTER";

// And another example
var thing = 'template strings';
console.log(`Say hello to ${thing}.`);

// => Say hello to template strings

Wenn der String mit Graviszeichen versehen sein soll, verwenden Sie zum Escapezeichen den umgekehrten Schrägstrich \ wie folgt:

var greeting = `\`Yo\` World!`;

Mehrzeilige Strings

Mehrzeilige Zeichenfolgen in JavaScript erfordern seit einiger Zeit Hacky-Problemumgehungen. Aktuelle Lösungen erfordern, dass Strings entweder in einer einzelnen Zeile vorhanden sind oder in mehrzeilige Strings aufgeteilt werden. Verwenden Sie dazu einen umgekehrten Schrägstrich (\) vor jedem Zeilenumbruch. Beispiel:

var greeting = "Yo \
World";

Obwohl dies in den meisten modernen JavaScript-Engines gut funktionieren sollte, ist das Verhalten selbst noch ein Hacking-Angriff. Sie können auch die String-Verkettung verwenden, um die Unterstützung mehrerer Zeilen vorzutäuschen. Das lässt aber auch etwas zu wünschen übrig:

var greeting = "Yo " +
"World";

Vorlagenstrings vereinfachen mehrzeilige Strings erheblich. Fügen Sie einfach Zeilenumbrüche ein, wo sie benötigt werden, und BOOM. Beispiel:

Leerzeichen innerhalb der Backtick-Syntax werden ebenfalls als Teil des Strings betrachtet.

console.log(`string text line 1
string text line 2`);

Getaggte Vorlagen

Bisher haben wir uns mit Vorlagenstrings für die Stringersetzung und zum Erstellen mehrzeiliger Strings beschäftigt. Eine weitere leistungsstarke Funktion sind getaggte Vorlagen. Mit Tags versehene Vorlagen transformieren einen Vorlagenstring, indem ein Funktionsname vor die Vorlagenzeichenfolge platziert wird. Beispiel:

fn`Hello ${you}! You're looking ${adjective} today!`

Die Semantik eines getaggten Vorlagenstrings unterscheidet sich stark von der eines normalen Strings. Im Wesentlichen handelt es sich dabei um eine spezielle Art von Funktionsaufruf:

fn(["Hello ", "! You're looking ", " today!"], you, adjective);

Beachten Sie, wie das (n + 1)-te Argument der Substitution entspricht, die zwischen dem n-ten und (n + 1)-ten Eintrag im Zeichenfolgenarray erfolgt. Dies kann für alle möglichen Dinge nützlich sein, aber eine der einfachsten ist die automatische Maskierung interpolierter Variablen.

Sie könnten beispielsweise eine HTML-Escaping-Funktion schreiben, die...

html`<p title="${title}">Hello ${you}!</p>`

gibt einen String zurück, in dem die entsprechenden Variablen ersetzt, aber alle HTML-unsicheren Zeichen ersetzt wurden. Legen wir los. Unsere HTML-Escape-Funktion nimmt zwei Argumente an: einen Nutzernamen und einen Kommentar. Beide können unsichere HTML-Zeichen enthalten (nämlich ', ', <, > und &). Lautet der Nutzername beispielsweise "Domenic Denicola" und der Kommentar lautet "& is a fun tag", wird Folgendes ausgegeben:

<b>Domenic Denicola says:</b> "&amp; is a fun tag"

Unsere getaggte Vorlagenlösung könnte somit so geschrieben werden:

// HTML Escape helper utility
var util = (function () {
    // Thanks to Andrea Giammarchi
    var
    reEscape = /[&<>'"]/g,
    reUnescape = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g,
    oEscape = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        "'": '&#39;',
        '"': '&quot;'
    },
    oUnescape = {
        '&amp;': '&',
        '&#38;': '&',
        '&lt;': '<',
        '&#60;': '<',
        '&gt;': '>',
        '&#62;': '>',
        '&apos;': "'",
        '&#39;': "'",
        '&quot;': '"',
        '&#34;': '"'
    },
    fnEscape = function (m) {
        return oEscape[m];
    },
    fnUnescape = function (m) {
        return oUnescape[m];
    },
    replace = String.prototype.replace
    ;
    return (Object.freeze || Object)({
    escape: function escape(s) {
        return replace.call(s, reEscape, fnEscape);
    },
    unescape: function unescape(s) {
        return replace.call(s, reUnescape, fnUnescape);
    }
    });
}());

// Tagged template function
function html(pieces) {
    var result = pieces[0];
    var substitutions = [].slice.call(arguments, 1);
    for (var i = 0; i < substitutions.length; ++i) {
        result += util.escape(substitutions[i]) + pieces[i + 1];
    }

    return result;
}

var username = "Domenic Denicola";
var tag = "& is a fun tag";
console.log(html`<b>${username} says</b>: "${tag}"`);
//=> <b>Domenic Denicola says</b>: "&amp; is a fun tag"

Weitere Anwendungsmöglichkeiten sind automatisches Escaping, Formatierungen, Lokalisierung und im Allgemeinen komplexere Substitutionen:

// Contextual auto-escaping
qsa`.${className}`;
safehtml`<a href="${url}?q=${query}" onclick="alert('${message}')" style="color: ${color}">${message}</a>`;

// Localization and formatting
l10n`Hello ${name}; you are visitor number ${visitor}:n! You have ${money}:c in your account!`

// Embedded HTML/XML
jsx`<a href="${url}">${text}</a>` // becomes React.DOM.a({ href: url }, text)

// DSLs for code execution
var childProcess = sh`ps ax | grep ${pid}`;

Zusammenfassung

Vorlagenstrings sind in Chrome 41 (Beta+), IE Tech Preview, Firefox 35 und höher und io.js verfügbar. Wenn Sie sie heute in der Produktion verwenden möchten, werden sie von den wichtigsten ES6-Transpilern wie Traceur und 6to5 unterstützt. Wenn Sie sie ausprobieren möchten, sehen Sie sich unser Beispiel für Vorlagenstrings im Chrome-Beispiel-Repository an. Vielleicht sind Sie auch an den ES6-Äquivalenten in ES5 interessiert, die zeigen, wie Sie einige der sugaring-Vorlagen-Strings mit ES5 heute umsetzen können.

Vorlagenstrings bringen viele wichtige Funktionen in JavaScript. Dazu gehören bessere Möglichkeiten zur String- und Ausdrucksinterpolation, mehrzeilige Strings und die Möglichkeit, eigene DSLs zu erstellen.

Eine der bedeutendsten Funktionen, die sie mitbringen, sind getaggte Vorlagen – eine wichtige Funktion für die Entwicklung solcher DSLs. Sie erhalten die Teile eines Vorlagenstrings als Argumente und Sie können dann entscheiden, wie die Strings und Substitutionen verwendet werden sollen, um die endgültige Ausgabe Ihres Strings zu bestimmen.

Weiterführende Literatur