Шаблонні рядки записують у зворотних лапках `. Вони підтримують підстановку виразів і багаторядковість:
const name = 'Оля';
const count = 3;
const message = `Привіт, ${name}! У вас ${count} нових ${count === 1 ? 'повідомлення' : 'повідомлень'}.`;
const html = `
<div class="card">
<h3>${title}</h3>
</div>
`;
Усередині ${...} - будь-який вираз: виклик функції, тернарний оператор, арифметика. Результат перетворюється на рядок.
Чим кращі за склеювання через +:
- читається як готовий текст, без нагромадження лапок і плюсів;
- переноси рядків зберігаються як є;
- не треба екранувати одинарні й подвійні лапки всередині.
Пастки:
- HTML з даними користувача через шаблонний рядок і
innerHTML- XSS. Шаблонний рядок нічого не екранує; - відступи багаторядкового шаблону потрапляють у рядок;
undefinedіnullпідставляться як текст'undefined'/'null'- видно в інтерфейсі, якщо дані не прийшли.
Теговані шаблони - функція перед шаблоном отримує окремо статичні частини й підставлені значення:
function highlight(strings, ...values) {
return strings.reduce(
(result, part, i) => result + part + (i < values.length ? `<mark>${escapeHtml(values[i])}</mark>` : ''),
'',
);
}
highlight`Знайдено ${count} результатів для «${query}»`;
Функція бачить, де закінчується довірений текст розробника і починаються дані, - і може їх обробити: екранувати, параметризувати.
Де теговані шаблони використовують:
- безпечний SQL: бібліотеки на кшталт
postgres(sql`SELECT * FROM users WHERE id = ${id}`) перетворюють значення на параметри запиту, а не вставляють у текст - захист від SQL-ін'єкцій; - HTML-шаблони з екрануванням:
lit-html(html`<p>${text}</p>`); - CSS-in-JS: styled-components;
- GraphQL-запити:
gql`...`; String.raw- вбудований тег, що не обробляє екранування:String.raw`C:\new\path`лишає\nяк два символи. Зручно для регулярних виразів і шляхів Windows.
Масив статичних частин має властивість raw - ті самі частини без обробки екранування.