--- 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")}}