--- title: Шаблонні літерали (шаблонні рядки) slug: Web/JavaScript/Reference/Template_literals tags: - ECMAScript 2015 - JavaScript - String - Посібник - рядок - шаблонні літерали - шаблонні рядки translation_of: Web/JavaScript/Reference/Template_literals ---
Шаблонні літерали - це рядкові літерали, які дозволяють використання вбудованих виразів. З ними ви можете використовувати багаторядковий запис та засоби інтерполяції рядків.
У попередніх версіях специфікації ES2015 вони називались "шаблонними рядками".
`текстовий рядок`
`текстовий рядок 1
текстовий рядок 2`
`текст ${вираз} текст`
тег`текст ${вираз} текст`
Шаблонні літерали заключаються у зворотні лапки (` `) (гравіс) замість подвійних чи одинарних лапок.
Шаблонні літерали можуть містити заповнювачі. Вони позначаються знаком долара та фігурними дужками (${вираз}). Вирази у заповнювачах та текст між зворотними лапками (` `) передаються у функцію.
Проста функція просто з'єднує декілька частин у єдиний рядок. Якщо перед шаблоном знаходиться вираз (тег), він називається тегованим шаблоном. У цьому випадку вираз тегу (зазвичай, це функція) викликається разом із шаблонним літералом, і ви можете маніпулювати ним перед поверненням.
Щоб екранувати зворотні лапки у шаблонному літералі, поставте зворотній слеш (\) перед лапками.
`\`` === '`' // --> true
Будь-які символи нового рядка, вставлені у першокод, є частиною шаблонного літералу.
У звичайних рядках вам довелося б використати наступний синтаксис, щоб отримати багаторядковий запис:
console.log('текстовий рядок 1\n' +
'текстовий рядок 2');
// "текстовий рядок 1
// текстовий рядок 2"
У шаблонних літералах ви можете зробити те саме ось так:
console.log(`текстовий рядок 1 текстовий рядок 2`); // "текстовий рядок 1 // текстовий рядок 2"
Для того, щоб вставити вирази у звичайні рядки, ви б використали наступний синтаксис:
let a = 5;
let b = 10;
console.log('П\'ятнадцять - це ' + (a + b) + ', а\nне ' + (2 * a + b) + '.');
// "П'ятнадцять - це 15, а
// не 20."
Тепер, з шаблонними літералами, ви можете скористатись синтаксичним цукром, зробивши підстановки легшими для читання наступним чином:
let a = 5;
let b = 10;
console.log(`П'ятнадцять - це ${a + b}, а
не ${2 * a + b}.`);
// "П'ятнадцять - це 15, а
// не 20."
У певних випадках вкладений шаблон - це найкращий (і, мабуть, найлегший для читання) спосіб створювати рядки, що конфігуруються. Всередині шаблона у зворотних лапках легко створити внутрішні зворотні лапки, просто використавши їх всередині заповнювача ${ } у шаблоні.
Наприклад, якщо умова a дорівнює true, то повернути цей шаблонований літерал.
У ES5:
let classes = 'header'; classes += (isLargeScreen() ? '' : item.isCollapsed ? ' icon-expander' : ' icon-collapser');
У ES2015 з шаблонними літералами та без вкладення:
const classes = `header ${ isLargeScreen() ? '' :
(item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;
У ES2015 з вкладеними шаблонними літералами:
const classes = `header ${ isLargeScreen() ? '' :
`icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;
Більш прогресивною формою шаблонних літералів є теговані шаблони.
Теги дозволяють розбирати шаблонні літерали за допомого функцій. Перший аргумент функції-тегу містить масив рядкових значень. Решта аргументів відносяться до виразів.
Далі функція-тег може виконати будь-які операції над цими аргументами та повернути отриманий рядок. (Як варіант, вона може повернути щось зовсім інше, як описано у одному з наступних прикладів.)
Ім'я функції, що використовується для тегу, може бути яким завгодно.
let person = 'Майк';
let age = 28;
function myTag(strings, personExp, ageExp) {
let str0 = strings[0]; // "Цей "
let str1 = strings[1]; // " - "
// Технічно, існує рядок після
// останнього виразу (в нашому прикладі),
// але він порожній (""), тому не зважаємо.
// let str2 = strings[2];
let ageStr;
if (ageExp > 99){
ageStr = 'довгожитель';
} else {
ageStr = 'юнак';
}
// Ми навіть можемо повернути рядок, побудований шаблонним літералом
return `${str0}${personExp}${str1}${ageStr}`;
}
let output = myTag`Цей ${ person } - ${ age }`;
console.log(output);
// Цей Майк - юнак
Функція-тег може навіть не повертати рядок!
function template(strings, ...keys) {
return (function(...values) {
let dict = values[values.length - 1] || {};
let result = [strings[0]];
keys.forEach(function(key, i) {
let value = Number.isInteger(key) ? values[key] : dict[key];
result.push(value, strings[i + 1]);
});
return result.join('');
});
}
let t1Closure = template`${0}${1}${0}!`;
t1Closure('Й', 'О'); // "ЙОЙ!"
let t2Closure = template`${0} ${'foo'}!`;
t2Closure('Всім', {foo: 'привіт'}); // "Всім привіт!"
Спеціальна властивість raw, доступна на першому аргументі функції-тегу, дає доступ до сирих рядків у тому вигляді, як вони були записані, без обробки екранувань.
function tag(strings) {
console.log(strings.raw[0]);
}
tag`текстовий рядок 1 \n текстовий рядок 2`;
// виводить "текстовий рядок 1 \n текстовий рядок 2" ,
// в тому числі два символи, '\' та 'n'
На додачу, існує метод {{jsxref("String.raw()")}} для створення сирих рядків — так само, як їх би створили проста шаблонна функція та об'єднання рядків.
let str = String.raw`Привіт\n${2+3}!`;
// "Привіт\n5!"
str.length;
// 10
Array.from(str).join(',');
// "П,р,и,в,і,т,\,n,5,!"
У ECMAScript 2016 теговані шаблони відповідають правилам наступних екранованих послідовностей:
\u", наприклад, \u00A9\u{}", наприклад, \u{2F804}\x", наприклад, \xA9\0o", далі йде одна чи більше цифр, наприклад, \0o251Це означає, що тегований шаблон, наведений нижче, є проблематичним, оскільки, згідно з граматикою ECMAScript, синтаксичний аналізатор шукає коректну екрановану послідовність Юнікоду, але знаходить неправильно сформований синтаксис:
latex`\unicode` // Викидає помилку у старших версіях ECMAScript (ES2016 та старші) // SyntaxError: malformed Unicode character escape sequence
Теговані шаблони повинні дозволяти вкладені мови (наприклад, DSL чи LaTeX), де існують інші екрановані послідовності. Пропозиція ECMAScript Template Literal Revision (Стадія 4, має бути інтегрована у стандарт ECMAScript 2018) прибирає обмеження синтаксису екранованих послідовностей ECMAScript з тегованих шаблонів.
Однак, недозволені екрановані послідовності все одно мають бути представлені у “готовому” представленні. Вони з'являться як елемент {{jsxref("undefined")}} у масиві “cooked” (готовий):
function latex(str) {
return { "cooked": str[0], "raw": str.raw[0] }
}
latex`\unicode`
// { cooked: undefined, raw: "\\unicode" }
Зауважте, що обмеження екранованих послідовностей прибираються лише з тегованих шаблонів, вони не прибираються з нетегованих шаблонних літералів:
let bad = `погана екранована послідовність: \unicode`;
| Специфікація |
|---|
| {{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}} |
| {{SpecName('ESDraft', '#sec-tagged-templates', 'Tagged templates Literals')}} |
{{Compat("javascript.grammar.template_literals")}}