Template literals are string literals that allow embedding an expression. It is possible to use string interpolation and multi-line string features with them.
Replacing placeholders with values inside of a string literal is called string interpolation.
In JavaScript, there are 3 ways of defining a string:
// Single quote
const single = 'I am a string';
// Double quotes
const double = "I am a string";
// Backticks
const backticks = `I am a string`;
You are probably familiar with those 2 at the top but have you seen string in backticks ``
before?
Template literals are enclosed by the backticks ``
.
They can contain placeholders, which are enclosed by the dollar sign along with curly braces ${...}
.
The expressions, that are passed as placeholders are evaluated during the run-time and their result is inserted into the string.
Placeholders can contain basically everything:
${10}
${10 + 10}
${variable}
${example(10)}
Example using addition operation:
const string = `The result is: ${10 + 10}`;
console.log(string); // Prints "The result is: 20"
Example using function call:
const evaluate = (nr1, nr2) => nr1 + nr2;
const string = `The result is: ${evaluate(10, 10)}`;
console.log(string); // Prints "The result is: 20"
The placeholder expression result is implicitly converted to a string:
const number = 10;
// Variable "number" is evaluated to number "3.5"
// Afterwards, "3.5" is converted into a string
const string = `The result is: ${number}`;
console.log(string); // Prints "The result is: 10"
Important note: if the placeholder contains an object, method toString
is applied to it:
const numbers = [10, 20, 30];
// Method "numbers.toString()" is called
const string = `The result is: ${numbers}`;
console.log(string); // Prints "The result is: 10,20,30"
In the template strings, placeholder expressions have special meanings, so it's not possible to use the following pattern without escaping `I love ${apple}`
.
Let's try:
// ReferenceError: apple is not defined
const string = `I love ${apple}`;
In order to tell the interpreter to skip ${apple}
evaluation, you should use a backslash before the placeholder, like this: \${apple}
:
const string = `I love \${apple}`;
console.log(string); // Prints "I love ${apple}"
Before introducing template literal feature, JavaScript provided 3 ways of defining multi-line strings:
// Escaping newlines
"I am \
multi-line \
string";
// Concatenating strings
"I am " +
"multi-line " +
"string";
// Array of strings
[
"I am ",
"multi-line ",
"string"
].join('');
Those ways look ugly and contain some unnecessary markup. They can easily be rewritten using template literals:
`I am
multi-line
string`;
Nesting placeholders sometimes is the best and easiest method to get things done.
You are allowed to use single/double quotes or backticks inside of the placeholder:
const number10 = 10;
const number20 = 20;
const showNumber10 = true;
const showNumber20 = false;
const string = `
The result is: ${showNumber10 ? number10 : showNumber20 ? number20 : ``}
`;
console.log(string); // Prints: "The result is 10"
Tagged templates is a more advanced form of template literals.
Tags allow you to parse template literals with a function. The first argument of a tag function contains an array of string values. The remaining arguments are related to the expressions.
The tag function executes provided logic on the passed string and returns manipulated string:
const age = 18;
function cookieCounter(strings, personExp, ageExp) {
/*
These variables won't be used later on
They are present to show how you can access the input
*/
const str0 = strings[0]; // "The person is "
const str1 = strings[1]; // " years old"
let cookiesNumber = 0;
if (age >= 18){
cookiesNumber = 5;
}
return `Allowed number of cookies: ${cookiesNumber}`;
};
const result = cookieCounter`The person is ${age} years old`;
console.log(result); // Prints "Allowed number of cookies: 5"
Important note: the first argument strings
in the function above contains raw
method which can be used to access raw input string:
const age = 18;
function cookieCounter(strings, personExp, ageExp) {
// Prints ["The person is ", " years old"]
console.log(strings.raw);
};
cookieCounter`The person is ${age} years old`;
Template literals allow us to put values inside of a string in a very readable and concise way and allow a clumsy concatenation approach.
``
${...}
\${apple}