Template literals zijn strings met daar binnengesloten een expressie. Ze zijn te gebruiken met meerdere regels, en ook met string interpolation, ook een kenmerk van Javascript. Ze werden in eerdere versies dan ES2015 ook wel "template strings" genoemd.
Syntax
`string text` `string text line 1 string text line 2` `string text ${expression} string text` tag `string text ${expression} string text`
Beschrijving
Template literals beginnen en eindigen met een back tick, het accent grave symbool (` `) (grave accent) in plaats van de gewone aanhalingstekens (" ") of apostrof (' '). Template literals kunnen bestaan uit placeholders. Deze worden aangegeven met een dollar-teken en vervolgens accolades (${expression}
). De expressie en tekst tussen de accolades worden doorgegeven aan een functie. The default functie plaatst alle delen achter elkaar. Als er een expressie voor de template literal staat, wordt de template string een tagged template literal genoemd. In dat geval wordt de expressie binnen de template literal doorgegeven aan de expressie (meestal een functie) zodat de template literal nog verder aangepast kan worden voordat de literal wordt weergegeven of doorgegeven.
let value = dummy`Ik ben ${name} en ik ben ${age} jaar`;
function dummy() {
let str = "";
strings.forEach((string, i) => {
str += string + values[i];
});
return str;
}
Om een back-tick in een template literal te gebruiken, moet er een backslash (\) voor de back-tick gebruikt worden (escaping).
`\`` === '`' // --> true
Meerdere regels
Any new line characters inserted in the source are part of the template literal. Using normal strings, you would have to use the following syntax in order to get multi-line strings:
Wordt binnen de template literal een nieuwe regel begonnen, dan maakt die regelopvoer deel uit van de template literal. Dit is anders dan met een gewone string; daar moet '\n' gebruikt worden om een string over meerdere regels toe te passen:
console.log('string text line 1\n' +
'string text line 2');
// "string text line 1
// string text line 2"
Bij een template literal kan '\n' weggelaten worden:
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"
Expression interpolation
Als er gerekend moet worden binnen een normale string, moet dat op de volgende manier gecodeerd worden:
var a = 5;
var b = 10;
console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
// "Fifteen is 15 and
// not 20."
Met een template literal hoeft dat niet; de expressie kan tussen de accolades gezet worden. Dat verbetert de leesbaarheid:
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and
not ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
Nesting templates
Soms kan de leebaarheid vergroot worden door template literals binnen een andere template literal te gebruiken (nesting). Met andere woorden, binnen de ${ }
mag ook weer een template literal, voorzien van back-ticks gebruikt worden. Bijvoorbeeld:
In ES5:
var classes = 'header'
classes += (isLargeScreen() ?
'' : item.isCollapsed ?
' icon-expander' : ' icon-collapser');
In ES2015 met template literals, zonder nesting:
const classes = `header ${ isLargeScreen() ? '' :
(item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;
In ES2015 nu met nested template literals:
const classes = `header ${ isLargeScreen() ? '' :
`icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;
Tagged template literals
Een geavanceerde vorm van template literals zijn de tagged template literals. Hiermee kan de template literal verder gemanipuleerd worden in een functie. De eerste parameter van de tag functie is een array met strings. De volgende parameters zijn gerelateerd aan de expressie. Uiteindelijk kan de de geretourneerde string compleet aangepast worden. De naam van de tag functie kan net zoals bij gewone functies, vrij gekozen worden:
var person = 'Mike';
var age = 28;
function myTag(strings, personExp, ageExp) {
var str0 = strings[0]; // "that "
var str1 = strings[1]; // " is a "
// There is technically a string after
// the final expression (in our example),
// but it is empty (""), so disregard.
// var str2 = strings[2];
var ageStr;
if (ageExp > 99){
ageStr = 'centenarian';
} else {
ageStr = 'youngster';
}
return str0 + personExp + str1 + ageStr;
}
var output = myTag`that ${ person } is a ${ age }`;
console.log(output);
// that Mike is a youngster
Het is overigens niet noodzakelijk dat een tag functie weer een string retourneert:
function template(strings, ...keys) {
return (function(...values) {
var dict = values[values.length - 1] || {};
var result = [strings[0]];
keys.forEach(function(key, i) {
var value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join('');
});
}
var t1Closure = template`${0}${1}${0}!`;
t1Closure('Y', 'A'); // "YAY!"
var t2Closure = template`${0} ${'foo'}!`;
t2Closure('Hello', {foo: 'World'}); // "Hello World!"
Raw strings
De speciale raw
property, een property van het eerste functie argument, maakt het mogelijk de oorspronkelijke strings te benaderen, zonder de escape sequences.
function tag(strings) {
console.log(strings.raw[0]);
}
tag`string text line 1 \n string text line 2`;
// logs "string text line 1 \n string text line 2" ,
// including the two characters '\' and 'n'
De "String.raw()" method kan gebruikt worden om strings te maken op dezelfde manier als de standaard template function:
var str = String.raw`Hi\n${2+3}!`;
// "Hi\n5!"
str.length;
// 6
str.split('').join(',');
// "H,i,\,n,5,!"
Tagged template literals and escape sequences
Volgens de ES2016 spec, tagged template literals conformeren zich tot de volgende escape reeksen:
- Unicode escapes beginnen met "\u", bijvoorbeeld
\u00A9
- Unicode code point escapes; hier wordt "\u{}" gebruikt, bijvoorbeeld \
u{2F804}
- Hexadecimal escapes beginnen met "\x", bijvoorbeeld
\xA9
- Octal literal escapes beginnen met "\" en een of meerdere getallen, bijvoorbeeld \251
Dit kan soms problemen geven:
latex`\unicode`
// Throws in older ECMAScript versions (ES2016 and earlier)
// SyntaxError: malformed Unicode character escape sequence
Tagged template literals zou andere taal elementen moeten toestaan, bijvoorbeeld DSLs of LaTeX waar andere escape reeksten normaal zijn. Het ECMAScript voorstel Template Literal Revision (stage 4, voor de ECMAScript 2018 standaard) zal hiermee rekening houden.
Escape reeksen zullen echter nu nog een undefined opleveren:
function latex(str) {
return { "cooked": str[0], "raw": str.raw[0] }
}
latex`\unicode`
// { cooked: undefined, raw: "\\unicode" }
Let op dat alleen de restrictie bij tagged template literals wordt opgeheven, en niet bij untagged template literals:
let bad = `bad escape sequence: \unicode`;
Specifications
Specification | Status | Comment |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Template Literals' in that specification. |
Standard | Initial definition. Defined in several section of the specification: Template Literals, Tagged Templates |
ECMAScript (ECMA-262) The definition of 'Template Literals' in that specification. |
Living Standard | Defined in several section of the specification: Template Literals, Tagged Templates |
Template Literal Revision | Stage 4 draft | Drops escape sequence restriction from tagged template literals |
Browser compatibility
BCD tables only load in the browser