aboutsummaryrefslogtreecommitdiff
path: root/files/uk/web/javascript/reference/template_literals/index.html
blob: fcd2c3adab8ce9ad3cb68d627a22a0e03e2f8979 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
---
title: Шаблонні літерали (шаблонні рядки)
slug: Web/JavaScript/Reference/Template_literals
tags:
  - ECMAScript 2015
  - JavaScript
  - String
  - Посібник
  - рядок
  - шаблонні літерали
  - шаблонні рядки
translation_of: Web/JavaScript/Reference/Template_literals
---
<div>{{JsSidebar("More")}}</div>

<p><span class="seoSummary">Шаблонні літерали - це рядкові літерали, які дозволяють використання вбудованих виразів. З ними ви можете використовувати багаторядковий запис та засоби інтерполяції рядків. </span></p>

<p>У попередніх версіях специфікації ES2015 вони називались "шаблонними рядками".</p>

<h2 id="Синтаксис">Синтаксис</h2>

<pre class="syntaxbox">`текстовий рядок`

`текстовий рядок 1
 текстовий рядок 2`

`текст ${<var>вираз</var>} текст`

<var>тег</var>`текст ${<var>вираз</var>} текст`
</pre>

<h2 id="Опис">Опис</h2>

<p>Шаблонні літерали заключаються у зворотні лапки (` `) (<a href="https://uk.wikipedia.org/wiki/%D0%93%D1%80%D0%B0%D0%B2%D1%96%D1%81_(%D0%B4%D1%96%D0%B0%D0%BA%D1%80%D0%B8%D1%82%D0%B8%D1%87%D0%BD%D0%B8%D0%B9_%D0%B7%D0%BD%D0%B0%D0%BA)">гравіс</a>) замість подвійних чи одинарних лапок.</p>

<p>Шаблонні літерали можуть містити заповнювачі. Вони позначаються знаком долара та фігурними дужками (<code>${вираз}</code>). Вирази у заповнювачах та текст між зворотними лапками (` `) передаються у функцію.</p>

<p>Проста функція просто з'єднує декілька частин у єдиний рядок. Якщо перед шаблоном знаходиться вираз (<code>тег</code>), він називається <dfn><em>тегованим шаблоном</em></dfn>. У цьому випадку вираз тегу (зазвичай, це функція) викликається разом із шаблонним літералом, і ви можете маніпулювати ним перед поверненням.</p>

<p>Щоб екранувати зворотні лапки у шаблонному літералі, поставте зворотній слеш (<code>\</code>)<strong> </strong>перед лапками.</p>

<pre class="brush: js">`\`` === '`' // --&gt; true</pre>

<h3 id="Багаторядковий_запис">Багаторядковий запис</h3>

<p>Будь-які символи нового рядка, вставлені у першокод, є частиною шаблонного літералу.</p>

<p>У звичайних рядках вам довелося б використати наступний синтаксис, щоб отримати багаторядковий запис:</p>

<pre class="brush: js">console.log('текстовий рядок 1\n' +
'текстовий рядок 2');
// "текстовий рядок 1
// текстовий рядок 2"</pre>

<p>У шаблонних літералах ви можете зробити те саме ось так:</p>

<pre class="brush: js">console.log(`текстовий рядок 1
текстовий рядок 2`);
// "текстовий рядок 1
// текстовий рядок 2"</pre>

<h3 id="Інтерполяція_виразів">Інтерполяція виразів</h3>

<p>Для того, щоб вставити вирази у звичайні рядки, ви б використали наступний синтаксис:</p>

<pre class="brush: js">let a = 5;
let b = 10;
console.log('П\'ятнадцять - це ' + (a + b) + ', а\nне ' + (2 * a + b) + '.');
// "П'ятнадцять - це 15, а
// не 20."</pre>

<p>Тепер, з шаблонними літералами, ви можете скористатись синтаксичним цукром, зробивши підстановки легшими для читання наступним чином:</p>

<pre class="brush: js">let a = 5;
let b = 10;
console.log(`П'ятнадцять - це ${a + b}, а
не ${2 * a + b}.`);
// "П'ятнадцять - це 15, а
// не 20."</pre>

<h3 id="Вкладені_шаблони">Вкладені шаблони</h3>

<p>У певних випадках вкладений шаблон - це найкращий (і, мабуть, найлегший для читання) спосіб створювати рядки, що конфігуруються. Всередині шаблона у зворотних лапках легко створити внутрішні зворотні лапки, просто використавши їх всередині заповнювача <code>${ }</code> у шаблоні.</p>

<p>Наприклад, якщо умова a дорівнює <code>true</code>, то повернути цей шаблонований літерал.</p>

<p>У ES5:</p>

<pre class="brush: js">let classes = 'header';
classes += (isLargeScreen() ?
  '' : item.isCollapsed ?
    ' icon-expander' : ' icon-collapser');
</pre>

<p>У ES2015 з шаблонними літералами та без вкладення:</p>

<pre class="brush: js">const classes = `header ${ isLargeScreen() ? '' :
  (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;</pre>

<p>У ES2015 з вкладеними шаблонними літералами:</p>

<pre class="brush: js">const classes = `header ${ isLargeScreen() ? '' :
  `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;</pre>

<h3 id="Теговані_шаблони">Теговані шаблони</h3>

<p>Більш прогресивною формою шаблонних літералів є <em>теговані</em> шаблони.</p>

<p>Теги дозволяють розбирати шаблонні літерали за допомого функцій. Перший аргумент функції-тегу містить масив рядкових значень. Решта аргументів відносяться до виразів.</p>

<p>Далі функція-тег може виконати будь-які операції над цими аргументами та повернути отриманий рядок. (Як варіант, вона може повернути щось зовсім інше, як описано у одному з наступних прикладів.) </p>

<p>Ім'я функції, що використовується для тегу, може бути яким завгодно.</p>

<pre class="brush: js">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 &gt; 99){
    ageStr = 'довгожитель';
  } else {
    ageStr = 'юнак';
  }

  // Ми навіть можемо повернути рядок, побудований шаблонним літералом
  return `${str0}${personExp}${str1}${ageStr}`;
}

let output = myTag`Цей ${ person } - ${ age }`;

console.log(output);
// Цей Майк - юнак</pre>

<p>Функція-тег може навіть не повертати рядок!</p>

<pre class="brush: js">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: 'привіт'});       // "Всім привіт!"
</pre>

<h3 id="Сирі_рядки">Сирі рядки</h3>

<p>Спеціальна властивість <code>raw</code>, доступна на першому аргументі функції-тегу, дає доступ до сирих рядків у тому вигляді, як вони були записані, без обробки <a href="/uk/docs/Web/JavaScript/Guide/Grammar_and_types#Використання_спеціальних_символів_у_рядках">екранувань</a>.</p>

<pre class="brush: js">function tag(strings) {
  console.log(strings.raw[0]);
}

tag`текстовий рядок 1 \n текстовий рядок 2`;
// виводить "текстовий рядок 1 \n текстовий рядок 2" ,
// в тому числі два символи, '\' та 'n'
</pre>

<p>На додачу, існує метод {{jsxref("String.raw()")}} для створення сирих рядків — так само, як їх би створили проста шаблонна функція та об'єднання рядків.</p>

<pre class="brush: js">let str = String.raw`Привіт\n${2+3}!`;
// "Привіт\n5!"

str.length;
// 10

Array.from(str).join(',');
// "П,р,и,в,і,т,\,n,5,!"
</pre>

<h3 id="Теговані_шаблони_та_екрановані_послідовності">Теговані шаблони та екрановані послідовності</h3>

<h4 id="Поведінка_в_ES2016">Поведінка в ES2016</h4>

<p>У ECMAScript 2016 теговані шаблони відповідають правилам наступних екранованих послідовностей:</p>

<ul>
 <li>Послідовності Юнікоду починаються з "<code>\u</code>", наприклад, <code>\u00A9</code></li>
 <li>Екранування кодів символів Юнікоду позначаються через "<code>\u{}</code>", наприклад, <code>\u{2F804}</code></li>
 <li>Шістнадцяткові послідовності починаються з "<code>\x</code>", наприклад, <code>\xA9</code></li>
 <li>Вісімкові літеральні послідовності починаються з "<code>\0o</code>", далі йде одна чи більше цифр, наприклад, <code>\0o251</code></li>
</ul>

<p>Це означає, що тегований шаблон, наведений нижче, є проблематичним, оскільки, згідно з граматикою ECMAScript, синтаксичний аналізатор шукає коректну екрановану послідовність Юнікоду, але знаходить неправильно сформований синтаксис:</p>

<pre class="brush: js">latex`\unicode`
// Викидає помилку у старших версіях ECMAScript (ES2016 та старші)
// SyntaxError: malformed Unicode character escape sequence</pre>

<h4 id="Перегляд_недозволених_екранованих_послідовностей_у_ES2018">Перегляд недозволених екранованих послідовностей у ES2018</h4>

<p>Теговані шаблони повинні дозволяти вкладені мови (наприклад, <a href="https://uk.wikipedia.org/wiki/%D0%9F%D1%80%D0%B5%D0%B4%D0%BC%D0%B5%D1%82%D0%BD%D0%BE-%D0%BE%D1%80%D1%96%D1%94%D0%BD%D1%82%D0%BE%D0%B2%D0%B0%D0%BD%D0%B0_%D0%BC%D0%BE%D0%B2%D0%B0_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D1%83%D0%B2%D0%B0%D0%BD%D0%BD%D1%8F">DSL</a> чи <a href="https://uk.wikipedia.org/wiki/LaTeX">LaTeX</a>), де існують інші екрановані послідовності. Пропозиція ECMAScript <a href="https://tc39.github.io/proposal-template-literal-revision/">Template Literal Revision</a> (Стадія 4, має бути інтегрована у стандарт ECMAScript 2018) прибирає обмеження синтаксису екранованих послідовностей ECMAScript з тегованих шаблонів.</p>

<p>Однак, недозволені екрановані послідовності все одно мають бути представлені у “готовому” представленні. Вони з'являться як елемент {{jsxref("undefined")}} у масиві “cooked” (готовий):</p>

<pre class="brush: js">function latex(str) {
  return { "cooked": str[0], "raw": str.raw[0] }
}

latex`\unicode`

// { cooked: undefined, raw: "\\unicode" }</pre>

<p>Зауважте, що обмеження екранованих послідовностей прибираються лише з <em>тегованих</em> шаблонів, вони не прибираються з <em>нетегованих</em> шаблонних літералів:</p>

<pre class="brush: js example-bad">let bad = `погана екранована послідовність: \unicode`;</pre>

<h2 id="Специфікації">Специфікації</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Специфікація</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-tagged-templates', 'Tagged templates Literals')}}</td>
  </tr>
 </tbody>
</table>

<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2>

<div>


<p>{{Compat("javascript.grammar.template_literals")}}</p>
</div>

<h2 id="Див._також">Див. також</h2>

<ul>
 <li>{{jsxref("String")}}</li>
 <li>{{jsxref("String.raw()")}}</li>
 <li><a href="/uk/docs/Web/JavaScript/Reference/Lexical_grammar">Лексична граматика</a></li>
 <li><a href="https://gist.github.com/WebReflection/8f227532143e63649804">Подібні до шаблонів рядки у сумісному з ES3 синтаксисі</a></li>
 <li><a href="https://hacks.mozilla.org/2015/05/es6-in-depth-template-strings-2/">"ES6 в подробицях: Шаблонні рядки" на hacks.mozilla.org</a></li>
</ul>