aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/template_strings/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/ru/web/javascript/reference/template_strings/index.html')
-rw-r--r--files/ru/web/javascript/reference/template_strings/index.html243
1 files changed, 243 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/template_strings/index.html b/files/ru/web/javascript/reference/template_strings/index.html
new file mode 100644
index 0000000000..d8b4b9a442
--- /dev/null
+++ b/files/ru/web/javascript/reference/template_strings/index.html
@@ -0,0 +1,243 @@
+---
+title: Шаблонные строки
+slug: Web/JavaScript/Reference/template_strings
+tags:
+ - ECMAScript6
+ - JavaScript
+ - Строки
+ - Шаблонные строки
+ - Экспериментальный
+translation_of: Web/JavaScript/Reference/Template_literals
+---
+<div>{{JsSidebar("More")}}</div>
+
+<div>Шаблонными литералами называются строковые литералы, допускающие использование выражений внутри. С ними вы можете использовать многострочные литералы и строковую интерполяцию. В спецификациях до ES2015 они назывались "шаблонными строками".</div>
+
+<h2 id="Syntax" name="Syntax">Синтаксис</h2>
+
+<pre class="syntaxbox">`строка текста`
+
+`строка текста 1
+ строка текста 2`
+
+`строка текста ${выражение} строка текста`
+
+tag `строка текста ${выражение} строка текста`
+</pre>
+
+<h2 id="Description" name="Description">Описание</h2>
+
+<p>Шаблонные литералы заключены в обратные кавычки (` `) вместо двойных или одинарных. Они могут содержать подстановки, обозначаемые знаком доллара и фигурными скобками (<code>${выражение}</code>). Выражения в подстановках и текст между ними передаются в функцию. По умолчанию функция просто объединяет все части в строку. Если перед строкой есть выражение (здесь это <code>tag</code>), то шаблонная строка называется "теговым шаблоном". В этом случае, теговое выражение (обычно функция) вызывается с обработанным шаблонным литералом, который вы можете изменить перед выводом. Для экранирования обратной кавычки в шаблонных литералах указывается обратный слэш <strong>\</strong>.</p>
+
+<pre class="brush: js">`\`` === '`' // --&gt; true</pre>
+
+<h3 id="Многострочные_литералы">Многострочные литералы</h3>
+
+<p>Символы новой строки являются частью шаблонных литералов. Используя обычные строки, вставка переноса потребовала бы следующего синтаксиса:</p>
+
+<pre class="brush: js">console.log('string text line 1\n' +
+'string text line 2');
+// "string text line 1
+// string text line 2"</pre>
+
+<p>То же с использованием шаблонных литералов:</p>
+
+<pre class="brush: js">console.log(`string text line 1
+string text line 2`);
+// "string text line 1
+// string text line 2"</pre>
+
+<h3 id="Интерполяция_выражений">Интерполяция выражений</h3>
+
+<p>Для вставки выражений в обычные строки вам пришлось бы использовать следующий синтаксис:</p>
+
+<pre class="brush: js">var a = 5;
+var b = 10;
+console.log('Fifteen is ' + (a + b) + ' and not ' + (2 * a + b) + '.');
+// "Fifteen is 15 and not 20."</pre>
+
+<p>Теперь, при помощи шаблонных литералов, вам доступен "синтаксический сахар", делающий подстановки вроде той более читабельными:</p>
+
+<pre class="brush: js">var a = 5;
+var b = 10;
+console.log(`Fifteen is ${a + b} and not ${2 * a + b}.`);
+// "Fifteen is 15 and not 20."</pre>
+
+<h3 id="Вложенные_шаблоны">Вложенные шаблоны</h3>
+
+<p>Временами, вложить шаблон — это кратчайший и, возможно, более читабельный способ составить строку. Просто поместите внутрь шаблона с обратными кавычками ещё одни, обернув их в подстановку <code>${ }</code>. Например, если выражение истинно, можно вернуть шаблонный литерал.</p>
+
+<p>В ES5:</p>
+
+<pre class="brush: js">var 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>
+
+<pre class="brush: js">var person = 'Mike';
+var age = 28;
+
+function myTag(strings, personExp, ageExp) {
+ var str0 = strings[0]; // "That "
+ var str1 = strings[1]; // " is a "
+
+ // Технически, в конце итогового выражения
+ // (в нашем примере) есть ещё одна строка,
+ // но она пустая (""), так что пропустим её.
+ // var str2 = strings[2];
+
+ var ageStr;
+ if (ageExp &gt; 99){
+ ageStr = 'centenarian';
+ } else {
+ ageStr = 'youngster';
+ }
+
+ // Мы даже можем вернуть строку, построенную другим шаблонным литералом
+ return `${str0}${personExp}${str1}${ageStr}`;
+}
+
+var output = myTag`That ${ person } is a ${ age }`;
+
+console.log(output);
+// That Mike is a youngster</pre>
+
+<p>Функция тега не обязана возвращать строку, как показано в примере ниже:</p>
+
+<pre class="brush: js">function template(strings, ...keys) {
+ return (function(...values) {
+ var dict = values[values.length - 1] || {};
+ var result = [strings[0]];
+ keys.forEach(function(key, i) {
+ var value = Number.isInteger(key) ? values[key] : dict[key];
+ result.push(value, strings[i + 1]);
+ });
+ return result.join('');
+ });
+}
+
+var t1Closure = template`${0}${1}${0}!`;
+t1Closure('Y', 'A'); // "YAY!"
+var t2Closure = template`${0} ${'foo'}!`;
+t2Closure('Hello', {foo: 'World'}); // "Hello World!"
+</pre>
+
+<h3 id="Сырые_строки">Сырые строки</h3>
+
+<p>Специальное свойство <code>raw</code>, доступное для первого аргумента тегового шаблона, позволяет получить строку в том виде, в каком она была введена, без <a href="/ru/docs/Web/JavaScript/Guide/Grammar_and_types#Использование_специальных_символов_в_строках">экранирования</a>.</p>
+
+<pre class="brush: js">function tag(strings) {
+ return strings.raw[0];
+}
+
+tag`string text line 1 \\n string text line 2`;
+// выводит "string text line 1 \\n string text line 2",
+// включая 'n' и два символа '\'
+</pre>
+
+<p>Вдобавок, существует метод {{jsxref('String.raw()')}}, возвращающий точно такую же исходную строку, какую вернула бы функция шаблона по умолчанию и строковая конкатенация вместе.</p>
+
+<pre class="brush: js">var str = String.raw`Hi\n${2+3}!`;
+// "Hi\n5!"
+
+str.length;
+// 6
+
+str.split('').join(',');
+// "H,i,\,n,5,!"</pre>
+
+<h3 id="Теговые_шаблоны_и_экранирование_символов">Теговые шаблоны и экранирование символов</h3>
+
+<h4 id="Поведение_в_ES2016">Поведение в ES2016</h4>
+
+<p>В ECMAScript 2016 теговые шаблоны следуют правилам экранирования следующих символов:</p>
+
+<ul>
+ <li>символы Unicode, начинающиеся с "\u", например, <code>\u00A9</code></li>
+ <li>точки кода Unicode, начинающиеся с "\u{}", например, <code>\u{2F804}</code></li>
+ <li>шестнадцатеричные представления символов, начинающиеся с "\x", например, <code>\xA9</code></li>
+ <li>восьмеричные представления символов, начинающиеся с "\", например, <code>\251</code>​​​​​​</li>
+</ul>
+
+<p>Отсюда вытекает проблема теговых шаблонов: следуя грамматике ECMAScript, анализатор кода, найдя символ <code>\</code>, будет искать корректное представление символа Unicode, но может не найти его вовсе. Пример ниже показывает это:</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://ru.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%D0%B8%D0%B5%D0%BD%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D1%8B%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA">DSLs</a> или <a href="https://ru.wikipedia.org/wiki/LaTeX">LaTeX</a>), в которых широко используются многие другие экранирования. Предложение <a href="https://tc39.github.io/proposal-template-literal-revision/">Редакция шаблонных литералов</a> (уровень 4, одобренный к добавлению в стандарт ECMAScript 2018) устраняет синтаксические ограничения экранирования теговых шаблонов в ECMAScript.</p>
+
+<p>Однако, некорректное экранирование символов по-прежнему нужно отображать в "приготовленном" отображении. Оно показывается в виде {{jsxref("undefined")}} в "приготовленном" массиве:</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 = `bad escape sequence: \unicode`;</pre>
+
+<h2 id="Спецификации">Спецификации</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Спецификация</th>
+ <th scope="col">Статус</th>
+ <th scope="col">Комментарий</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}</td>
+ <td>{{Spec2('ES2015')}}</td>
+ <td>Изначальное определение. Определено в секциях <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-template-literals">Template Literals</a>, <a href="http://www.ecma-international.org/ecma-262/6.0/#sec-tagged-templates">Tagged Templates</a></td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}</td>
+ <td>{{Spec2('ESDraft')}}</td>
+ <td>Определено в секциях <a href="https://tc39.github.io/ecma262/#sec-template-literals">Template Literals</a>, <a href="https://tc39.github.io/ecma262/#sec-tagged-templates">Tagged Templates</a></td>
+ </tr>
+ <tr>
+ <td><a href="https://tc39.github.io/proposal-template-literal-revision/">Template Literal Revision</a></td>
+ <td>Черновик 4-го уровня</td>
+ <td>Устранено ограничение экранирования в теговых шаблонах</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2>
+
+<div class="hidden">Таблица совместимости на этой странице сгенерирована из автоматически получаемых данных. Если вы хотите внести свои данные, пожалуйста перейдите на <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам пул-реквест.</div>
+
+<p>{{Compat("javascript.grammar.template_literals")}}</p>
+
+<h2 id="Смотрите_также">Смотрите также</h2>
+
+<ul>
+ <li>{{jsxref("String")}}</li>
+ <li>{{jsxref("String.raw()")}}</li>
+ <li><a href="/en-US/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 в деталях: шаблонные строки</a></li>
+</ul>