From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../reference/template_strings/index.html | 243 +++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 files/ru/web/javascript/reference/template_strings/index.html (limited to 'files/ru/web/javascript/reference/template_strings') 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 +--- +
{{JsSidebar("More")}}
+ +
Шаблонными литералами называются строковые литералы, допускающие использование выражений внутри. С ними вы можете использовать многострочные литералы и строковую интерполяцию. В спецификациях до ES2015 они назывались "шаблонными строками".
+ +

Синтаксис

+ +
`строка текста`
+
+`строка текста 1
+ строка текста 2`
+
+`строка текста ${выражение} строка текста`
+
+tag `строка текста ${выражение} строка текста`
+
+ +

Описание

+ +

Шаблонные литералы заключены в обратные кавычки (` `) вместо двойных или одинарных. Они могут содержать подстановки, обозначаемые знаком доллара и фигурными скобками (${выражение}). Выражения в подстановках и текст между ними передаются в функцию. По умолчанию функция просто объединяет все части в строку. Если перед строкой есть выражение (здесь это tag), то шаблонная строка называется "теговым шаблоном". В этом случае, теговое выражение (обычно функция) вызывается с обработанным шаблонным литералом, который вы можете изменить перед выводом. Для экранирования обратной кавычки в шаблонных литералах указывается обратный слэш \.

+ +
`\`` === '`' // --> true
+ +

Многострочные литералы

+ +

Символы новой строки являются частью шаблонных литералов. Используя обычные строки, вставка переноса потребовала бы следующего синтаксиса:

+ +
console.log('string text line 1\n' +
+'string text line 2');
+// "string text line 1
+//  string text line 2"
+ +

То же с использованием шаблонных литералов:

+ +
console.log(`string text line 1
+string text line 2`);
+// "string text line 1
+//  string text line 2"
+ +

Интерполяция выражений

+ +

Для вставки выражений в обычные строки вам пришлось бы использовать следующий синтаксис:

+ +
var a = 5;
+var b = 10;
+console.log('Fifteen is ' + (a + b) + ' and not ' + (2 * a + b) + '.');
+// "Fifteen is 15 and not 20."
+ +

Теперь, при помощи шаблонных литералов, вам доступен "синтаксический сахар", делающий подстановки вроде той более читабельными:

+ +
var a = 5;
+var b = 10;
+console.log(`Fifteen is ${a + b} and not ${2 * a + b}.`);
+// "Fifteen is 15 and not 20."
+ +

Вложенные шаблоны

+ +

Временами, вложить шаблон — это кратчайший и, возможно, более читабельный способ составить строку. Просто поместите внутрь шаблона с обратными кавычками ещё одни, обернув их в подстановку ${ }. Например, если выражение истинно, можно вернуть шаблонный литерал.

+ +

В ES5:

+ +
var 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'}` }`;
+
+ +

Теговые шаблоны

+ +

Расширенной формой шаблонных литералов являются теговые шаблоны. Они позволяют разбирать шаблонные литералы с помощью функции. Первый аргумент такой функции содержит массив строковых значений, а остальные содержат выражения из подстановок. В итоге, функция должна вернуть собранную строку (или что-либо совсем иное, как будет показано далее). Имя функции может быть любым.

+ +
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 > 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
+ +

Функция тега не обязана возвращать строку, как показано в примере ниже:

+ +
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!"
+
+ +

Сырые строки

+ +

Специальное свойство raw, доступное для первого аргумента тегового шаблона, позволяет получить строку в том виде, в каком она была введена, без экранирования.

+ +
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' и два символа '\'
+
+ +

Вдобавок, существует метод {{jsxref('String.raw()')}}, возвращающий точно такую же исходную строку, какую вернула бы функция шаблона по умолчанию и строковая конкатенация вместе.

+ +
var str = String.raw`Hi\n${2+3}!`;
+// "Hi\n5!"
+
+str.length;
+// 6
+
+str.split('').join(',');
+// "H,i,\,n,5,!"
+ +

Теговые шаблоны и экранирование символов

+ +

Поведение в ES2016

+ +

В ECMAScript 2016 теговые шаблоны следуют правилам экранирования следующих символов:

+ + + +

Отсюда вытекает проблема теговых шаблонов: следуя грамматике ECMAScript, анализатор кода, найдя символ \, будет искать корректное представление символа Unicode, но может не найти его вовсе. Пример ниже показывает это:

+ +
latex`\unicode`
+// В старых версиях ECMAScript (ES2016 и раньше) выкинет исключение:
+// SyntaxError: malformed Unicode character escape sequence
+ +

Поведение в ES2018

+ +

Теговые шаблоны должны позволять встраивать языки (например, DSLs или LaTeX), в которых широко используются многие другие экранирования. Предложение Редакция шаблонных литералов (уровень 4, одобренный к добавлению в стандарт ECMAScript 2018) устраняет синтаксические ограничения экранирования теговых шаблонов в ECMAScript.

+ +

Однако, некорректное экранирование символов по-прежнему нужно отображать в "приготовленном" отображении. Оно показывается в виде {{jsxref("undefined")}} в "приготовленном" массиве:

+ +
function latex(str) {
+ return { "cooked": str[0], "raw": str.raw[0] }
+}
+
+latex`\unicode`
+
+// { cooked: undefined, raw: "\unicode" }
+ +

Заметьте, что ограничение на экранирование символов проявляется лишь в теговых шаблонах, и не проявляется в нетеговых шаблонных литералах:

+ +
let bad = `bad escape sequence: \unicode`;
+ +

Спецификации

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES2015')}}Изначальное определение. Определено в секциях Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Определено в секциях Template Literals, Tagged Templates
Template Literal RevisionЧерновик 4-го уровняУстранено ограничение экранирования в теговых шаблонах
+ +

Совместимость с браузерами

+ + + +

{{Compat("javascript.grammar.template_literals")}}

+ +

Смотрите также

+ + -- cgit v1.2.3-54-g00ecf