Ich habe den folgenden Code für Ecma-Script-6 template literals
let person = {name: 'John Smith'};
let tpl = `My name is ${person.name}.`;
let MyVar="My name is "+ person.name+".";
console.log("template literal= "+tpl);
console.log("my variable = "+MyVar);
Die Ausgabe ist wie folgt:
template literal= My name is John Smith.
my variable = My name is John Smith.
Das ist die Geige. Ich habe versucht, nach dem genauen Unterschied zu suchen, konnte ihn aber nicht finden. Meine Frage ist, was der Unterschied zwischen diesen beiden Aussagen ist.
let tpl = `My name is ${person.name}.`;
Und
let MyVar = "My name is "+ person.name+".";
Ich kann die Zeichenfolge hier bereits MyVar
verketten. In person.name
welchem Szenario sollte das Vorlagenliteral verwendet werden?
javascript
node.js
ecmascript-6
template-strings
Naeem Shaikh
quelle
quelle
tpl === MyVar
? Der einzige Unterschied ist die Syntax, mit der sie erstellt wurden. Beachten Sie, dass Vorlagen im Gegensatz zur Verkettung von Zeichenfolgen auch Tag-Funktionen bereitstellen, die beispielsweise für die automatische Escape-Funktion verwendet werden können.Antworten:
Wenn Sie Vorlagenliterale nur mit Platzhaltern (z. B.
`Hello ${person.name}`
) wie im Beispiel der Frage verwenden, entspricht das Ergebnis dem Verketten von Zeichenfolgen. Subjektiv sieht es besser aus und ist leichter zu lesen, insbesondere bei mehrzeiligen Zeichenfolgen oder Zeichenfolgen, die beide enthalten,'
und"
da Sie diesen Zeichen nicht mehr entkommen müssen.Die Lesbarkeit ist eine großartige Funktion, aber das Interessanteste an Vorlagen sind getaggte Vorlagenliterale :
let person = {name: 'John Smith'}; let tag = (strArr, name) => strArr[0] + name.toUpperCase() + strArr[1]; tag `My name is ${person.name}!` // Output: My name is JOHN SMITH!
In der dritten Zeile dieses Beispiels wird eine Funktion mit dem Namen
tag
aufgerufen. Der Inhalt der Vorlagenzeichenfolge ist in mehrere Variablen unterteilt, auf die Sie in den Argumenten dertag
Funktion zugreifen können : Literalabschnitte (in diesem Beispiel der Wert vonstrArr[0]
isMy name is
und der Wert vonstrArr[1]
is!
) und Substitutionen (John Smith
). Das Vorlagenliteral wird nach dem ausgewertet, was dietag
Funktion zurückgibt.Das ECMAScript-Wiki listet einige mögliche Anwendungsfälle auf, z. B. das automatische Escape- oder Codieren von Eingaben oder die Lokalisierung. Sie können eine Tag-Funktion mit dem Namen erstellen
msg
, die die wörtlichen Teile nachschlägtMy name is
und sie durch Übersetzungen in die Sprache des aktuellen Gebietsschemas ersetzt, z. B. ins Deutsche:console.log(msg`My name is ${person.name}.`) // Output: Mein Name ist John Smith.
Der von der Tag-Funktion zurückgegebene Wert muss nicht einmal eine Zeichenfolge sein. Sie können eine Tag-Funktion mit dem Namen erstellen,
$
die die Zeichenfolge auswertet und als Abfrageselektor verwendet, um eine Sammlung von DOM-Knoten zurückzugeben, wie in diesem Beispiel :$`a.${className}[href=~'//${domain}/']`
quelle
msg
Funktion. Sie könnten sicherlich auch die Substitutionswerte übersetzen.a.${className}[href=~'//${domain}/']
in Chromkonsole (und setzte vorclassName=''
unddomain=''
aber ich habe nicht den DOM - Knoten aber Array von Strings: / (in der anderen hadn, in jsfiddle wir Fehler in der Konsole erhalten: jsfiddle.net/d1fkta76 „Uncaught Reference : $ ist nicht definiert "- warum?ES6
Es wird eine neue Art von Zeichenfolgenliteral entwickelt, bei der das`
Back-Tick als Trennzeichen verwendet wird. Mit diesen Literalen können grundlegende Zeichenfolgeninterpolationsausdrücke eingebettet werden, die dann automatisch analysiert und ausgewertet werden.let actor = {name: 'RajiniKanth', age: 68}; let oldWayStr = "<p>My name is " + actor.name + ",</p>\n" + "<p>I am " + actor.age + " old</p>\n"; let newWayHtmlStr = `<p>My name is ${actor.name},</p> <p>I am ${actor.age} old</p>`; console.log(oldWayStr); console.log(newWayHtmlStr);
Wie Sie sehen können, haben wir das ..`` um eine Reihe von Zeichen verwendet, die als Zeichenfolgenliteral interpretiert werden. Alle Ausdrücke des Formulars
${..}
werden jedoch sofort analysiert und inline ausgewertet.Ein wirklich schöner Vorteil interpolierter String-Literale ist, dass sie sich über mehrere Zeilen verteilen dürfen:
var Actor = {"name" : "RajiniKanth"}; var text = `Now is the time for all good men like ${Actor.name} to come to the aid of their country!`; console.log( text ); // Now is the time for all good men // to come to the aid of their // country!
Interpolierte Ausdrücke
Jeder gültige Ausdruck darf
${..}
in einer interpolierten Zeichenfolge enthalten seinlit‐ eral
, einschließlich Funktionsaufrufen, Inline-Funktionsausdrucksaufrufen und sogar andereninterpo‐ lated string literals
!function upper(s) { return s.toUpperCase(); } var who = "reader" var text = `A very ${upper( "warm" )} welcome to all of you ${upper( `${who}s` )}!`; console.log( text ); // A very WARM welcome // to all of you READERS!
Hier war das innere interpolierte $ {who} s``-String-Literal für uns ein wenig angenehmer, wenn wir die who-Variable mit dem
"s"
String kombinierten , im Gegensatz zu who + "s". Um eine Notiz zu behalten, ist ein interpoliertes String-Literal genau dort,lexically scoped
wo es erscheint,dynamically scoped
in keiner Weisefunction foo(str) { var name = "foo"; console.log( str ); } function bar() { var name = "bar"; foo( `Hello from ${name}!` ); } var name = "global"; bar(); // "Hello from bar!"
Die Verwendung des
template literal
für den HTML-Code ist definitiv besser lesbar, da der Ärger verringert wird.Der einfache alte Weg:
'<div class="' + className + '">' + '<p>' + content + '</p>' + '<a href="' + link + '">Let\'s go</a>' '</div>';
Mit
ES6
:`<div class="${className}"> <p>${content}</p> <a href="${link}">Let's go</a> </div>`
Verschlagwortet mit Vorlagenliterale
Wir können auch eine
template
Zeichenfolge markieren . Wenn einetemplate
Zeichenfolge markiert wird, werden dieliterals
Ersetzungen und an die Funktion übergeben, die den resultierenden Wert zurückgibt.function myTaggedLiteral(strings) { console.log(strings); } myTaggedLiteral`test`; //["test"] function myTaggedLiteral(strings,value,value2) { console.log(strings,value, value2); } let someText = 'Neat'; myTaggedLiteral`test ${someText} ${2 + 3}`; // ["test ", " ", ""] // "Neat" // 5
Wir können den
spread
Operator hier verwenden, um mehrere Werte zu übergeben. Das erste Argument - wir haben es Strings genannt - ist ein Array aller einfachen Strings (das Zeug zwischen interpolierten Ausdrücken).Wir sammeln dann alle nachfolgenden Argumente in einem Array namens values mit dem
... gather/rest operator
, obwohl Sie sie natürlich als einzelne benannte Parameter belassen könnten, die dem string-Parameter folgen, wie wir es oben getan haben(value1, value2 etc)
.function myTaggedLiteral(strings,...values) { console.log(strings); console.log(values); } let someText = 'Neat'; myTaggedLiteral`test ${someText} ${2 + 3}`; // ["test ", " ", ""] // ["Neat", 5]
Das
argument(s)
in unserem Wertearray gesammelte Ergebnis sind die Ergebnisse der bereits ausgewerteten Interpolationsausdrücke, die im Zeichenfolgenliteral enthalten sind. Atagged string literal
ist wie ein Verarbeitungsschritt, nachdem die Interpolationen ausgewertet wurden, aber bevor der endgültige Zeichenfolgenwert kompiliert wurde, sodass Sie mehr Kontrolle über das Generieren der Zeichenfolge aus dem Literal haben. Schauen wir uns ein Beispiel für die Erstellung einesre-usable templates
.const Actor = { name: "RajiniKanth", store: "Landmark" } const ActorTemplate = templater`<article> <h3>${'name'} is a Actor</h3> <p>You can find his movies at ${'store'}.</p> </article>`; function templater(strings, ...keys) { return function(data) { let temp = strings.slice(); keys.forEach((key, i) => { temp[i] = temp[i] + data[key]; }); return temp.join(''); } }; const myTemplate = ActorTemplate(Actor); console.log(myTemplate);
Rohe Saiten
Unsere Tag-Funktionen erhalten ein erstes Argument, das wir aufgerufen
strings
habenarray
. Es sind jedoch noch einige weitere Daten enthalten: die unverarbeiteten Rohversionen aller Zeichenfolgen. Sie können mit der.raw
Eigenschaft wie folgt auf diese unformatierten Zeichenfolgenwerte zugreifen :function showraw(strings, ...values) { console.log( strings ); console.log( strings.raw ); } showraw`Hello\nWorld`;
Wie Sie sehen können,
raw
behält die Version der Zeichenfolge die maskierte \ n-Sequenz bei, während die verarbeitete Version der Zeichenfolge sie wie eine echte neue Zeile behandelt.ES6
kommt mit einer eingebauten Funktion, die als String-Literal-Tag verwendet werden kann :String.raw(..)
. Es geht einfach durch die Rohversionen vonstrings
:console.log( `Hello\nWorld` ); /* "Hello World" */ console.log( String.raw`Hello\nWorld` ); // "Hello\nWorld"
quelle
Es ist viel sauberer und, wie in den Kommentaren angegeben, in anderen Sprachen üblich. Das andere, was ich nett fand, waren die Zeilenumbrüche, die beim Schreiben von Strings sehr nützlich waren.
let person = {name: 'John Smith', age: 24, greeting: 'Cool!' }; let usualHtmlStr = "<p>My name is " + person.name + ",</p>\n" + "<p>I am " + person.age + " old</p>\n" + "<strong>\"" + person.greeting +"\" is what I usually say</strong>"; let newHtmlStr = `<p>My name is ${person.name},</p> <p>I am ${person.age} old</p> <p>"${person.greeting}" is what I usually say</strong>`; console.log(usualHtmlStr); console.log(newHtmlStr);
quelle
Während meine Antwort die Frage nicht direkt anspricht. Ich dachte, es könnte von Interesse sein, auf einen Nachteil der Verwendung von Vorlagenliteralen zugunsten des Array-Joins hinzuweisen.
Sagen wir, ich habe
let patient1 = {firstName: "John", lastName: "Smith"}; let patient2 = {firstName: "Dwayne", lastName: "Johnson", middleName: "'The Rock'"};
Einige Patienten haben also einen zweiten Vornamen, andere nicht.
Wenn ich eine Zeichenfolge wollte, die den vollständigen Namen eines Patienten darstellt
let patientName = `${patient1.firstName} ${patient1.middleName} ${patient1.lastName}`;
Dann würde dies "John undefined Smith" werden
Aber wenn ich es tat
let patientName = [patient1.firstName, patient1.middleName, patient1.lastName].join(" ");
Dann würde dies nur "John Smith" werden
BEARBEITEN
General_Twyckenham wies darauf hin, dass ein Join auf "" zu einem zusätzlichen Leerzeichen zwischen "John" und "Smith" führen würde.
Um dies zu umgehen, können Sie vor dem Join einen Filter verwenden, um falsche Werte zu entfernen:
[patient1.firstName, patient1.middleName, patient1.lastName].filter(el => el).join(" ");
quelle
join
Version gibt Ihnen John Smith mit einem zusätzlichen Platz. Wie Sie sich vorstellen können, ist dies oft unerwünscht. Ein Fix dafür istmap
wie folgt zu verwenden :[patient1.firstName, patient1.middleName, patient1.lastName].map(el => el).join(" ");
filter
war die Funktion, die ich meinte.