Статьи

Гений шаблонных строк в ES6

ES6 — это будущее JavaScript, и оно уже здесь. Это законченная спецификация, и она содержит множество функций, которые требуются языку, чтобы оставаться конкурентоспособными с потребностями Интернета в настоящее время. Не все в ES6 для вас, и в этой небольшой серии постов я покажу функции, которые очень удобны и уже используются.

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

1
2
var animal = «cow»;
var animal = ‘cow’;

Причина, по которой я предпочитаю одинарные кавычки, заключается в том, что, во-первых, это облегчает сборку строк HTML с правильно указанными атрибутами, которые выглядят следующим образом:

1
2
3
4
5
6
7
8
9
// with single quotes, there’s no need to
// escape the quotes around the class value
var but = ‘<button class=»big»>Save</button>’;
 
// this is a syntax error:
var but = «<button class=»big»>Save</button>»;
 
// this works:
var but = «<button class=\»big\»>Save</button>»;

Единственный момент, когда вам нужно уйти, — это когда в вашем HTML используется одиночная кавычка, что должно быть очень редким случаем. Единственное, о чем я могу думать, это встроенный JavaScript или CSS, что означает, что вы, скорее всего, сделаете что-то неясное или отчаянное в своей разметке. Даже в ваших текстах вам, вероятно, лучше не использовать ни одной кавычки, а типографски более приятной ».

Кроме того: HTML, конечно, достаточно прощающий, чтобы опускать кавычки или использовать одинарные кавычки вокруг атрибута, но я предпочитаю создавать удобочитаемую разметку для людей, а не полагаться на прощение парсера. Мы сделали парсер HTML5 прощающим, потому что в прошлом люди писали ужасную разметку, а не как предлог продолжать это делать.

Я страдал достаточно в дни DHTML для document.write, создавая документ внутри набора фреймов в новом всплывающем окне и других мерзостях, чтобы больше не захотеть использовать escape-символ. Временами нам требовались тройные, и это было еще до того, как в наших редакторах было цветовое кодирование. Это был беспорядок.

Еще одна причина, по которой я предпочитаю одинарные кавычки, заключается в том, что я писал много PHP в свое время для очень больших веб-сайтов, где производительность имела большое значение. В PHP есть разница между одинарными и двойными кавычками. Строки в одинарных кавычках не имеют подстановки, в то время как в двойных -. Во времена PHP 3 и 4 это означало, что использование одинарных кавычек было намного быстрее, так как парсеру не приходилось проходить через строку для подстановки значений. Вот пример того, что это значит:

01
02
03
04
05
06
07
08
09
10
<?php
  $animal = ‘cow’;
  $sound = ‘moo’;
  
  echo ‘The animal is $animal and its sound is $sound’;
  // => The animal is $animal and its sound is $sound
  
  echo «The animal is $animal and its sound is $sound»;
  // => The animal is cow and its sound is moo
?>

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

1
2
3
4
5
6
var animal = ‘cow’;
var sound = ‘moo’;
 
alert(‘The animal is ‘ + animal + ‘ and its sound is ‘ +
 sound);
// => «The animal is cow and its sound is moo»

Это становится очень запутанным с более длинными и более сложными строками, особенно когда мы собираем много HTML. И, скорее всего, у вас рано или поздно появится инструмент для рисования, который будет жаловаться на пробел после пробела после + в конце строки. Это связано с тем, что в JavaScript нет многострочных строк:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
// this doesn’t work
var list = ‘<ul>
  <li>Buy Milk</li>
  <li>Be kind to Pandas</li>
  <li>Forget about Dre</li>
</ul>’;
  
// This does, but urgh…
var list = ‘<ul>\
  <li>Buy Milk</li>\
  <li>Be kind to Pandas</li>\
  <li>Forget about Dre</li>\
</ul>’;
  
// This is the most common way, and urgh, too…
var list = ‘<ul>’ +
‘ <li>Buy Milk</li>’ +
‘ <li>Be kind to Pandas</li>’ +
‘ <li>Forget about Dre</li>’ +
‘</ul>’;

Чтобы обойти беспорядок, связанный с обработкой строк и конкатенацией в JavaScript, мы сделали то, что делаем всегда — написали библиотеку. Существует много библиотек шаблонов HTML, и, вероятно, Mustache.js был оригинальным. Все они следуют своему нестандартному синтаксису и работают в этом духе. Это все равно, что сказать, что вы пишете свой контент в Markdown, а затем понять, что существует много разных идей о том, что означает «Markdown».

С появлением ES6 и его стандартизации мы можем радоваться, поскольку у JavaScript теперь есть новый ребёнок, когда дело доходит до обработки строк: Шаблонные строки . Обнадеживает поддержка строк шаблонов в современных браузерах : Chrome 44+, Firefox 38+, Microsoft Edge и WebKit — все на борту. Safari, к сожалению, нет, но он туда доберется.

Гениальность строк шаблона заключается в том, что он использует новый разделитель строк, который не используется ни в HTML, ни в обычных текстах: backtick ( ` ).

Используя это, мы теперь имеем подстановку строковых выражений в JavaScript:

1
2
3
4
5
var animal = ‘cow’;
var sound = ‘moo’;
  
alert(`The animal is ${animal} and its sound is ${sound}`);
// => «The animal is cow and its sound is moo»

Конструкция ${} может принимать любое выражение JavaScript, которое возвращает значение. Вы можете, например, выполнить вычисления или получить доступ к свойствам объекта:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
var out = `ten times two totally is ${ 10 * 2 }`;
// => «ten times two totally is 20»
  
var animal = {
  name: ‘cow’,
  ilk: ‘bovine’,
  front: ‘moo’,
  back: ‘milk’,
}
alert(`
  The ${animal.name} is of the
  ${animal.ilk} ilk,
  one end is for the ${animal.front},
  the other for the ${animal.back}
`);
// =>
/*
  The cow is of the
  bovine ilk,
  one end is for the moo,
  the other for the milk
*/

Последний пример также показывает, что многострочные строки больше не являются проблемой.

Еще одна вещь, которую вы можете сделать со строками шаблонов, это добавить их к тегу, который является именем вызываемой функции и получает строку в качестве параметра. Например, вы можете закодировать полученную строку для URL-адресов, не прибегая к ужасно названному encodeURIComponent все время.

01
02
03
04
05
06
07
08
09
10
11
12
13
function urlify (str) {
  return encodeURIComponent(str);
}
  
urlify `http://beedogs.com`;
// => «http%3A%2F%2Fbeedogs.com»
urlify `woah$£$%£^$»`;
// => «woah%24%C2%A3%24%25%C2%A3%5E%24%22»
  
// nesting also works:
  
var str = `foo ${urlify `&&`} bar`;
// => «foo %26%26 bar»

Это работает, но опирается на неявное приведение массива к строке. Параметр, отправляемый в функцию, является не строкой, а массивом строк и значений. Если использовать способ, показанный здесь, для удобства он преобразуется в строку, но правильный способ — получить прямой доступ к членам массива.

Внутри функции тега вы можете получить не только полную строку, но и ее части.

01
02
03
04
05
06
07
08
09
10
11
12
13
function tag (strings, values) {
  console.log(strings);
  console.log(values);
  console.log(strings[1]);
}
tag `you ${3+4} it`;
/* =>
  
Array [ «you «, » it» ]
7
it
  
*/

Вам также предоставляется массив необработанных строк, что означает, что вы получаете все символы в строке, включая управляющие символы. Например, вы добавляете разрыв строки с помощью \n . Вы получите двойной пробел в строке, но символы \n в необработанных строках:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
function tag (strings, values) {
  console.log(strings);
  console.log(values);
  console.log(strings[1]);
  console.log(string.raw[1]);
}
  
tag `you ${3+4} \nit`;
/* =>
  
Array [ «you «, » it» ]
7
  
it
 \nit
*/

Шаблонные строки — одна из тех изящных маленьких побед в ES6, которую можно использовать прямо сейчас. Если вам нужно поддерживать старые браузеры, вы, конечно, можете перенести ES6 на ES5; Вы можете выполнить проверку функциональности для поддержки строки шаблона, используя библиотеку, такую ​​как featuretests.io или с помощью следующего кода:

01
02
03
04
05
06
07
08
09
10
11
var templatestrings = false;
try {
  new Function( «`{2+2}`» );
  templatestrings = true;
} catch (err) {
  templatestrings = false;
}
  
if (templatestrings) {
    // …
}

Вот еще несколько статей о шаблонных строках:

Эта статья является частью серии веб-разработок от технических евангелистов Microsoft, посвященной практическому изучению JavaScript, проектам с открытым исходным кодом и рекомендациям по взаимодействию, включая браузер Microsoft Edge и новый механизм рендеринга EdgeHTML .

Мы рекомендуем вам протестировать браузеры и устройства, включая Microsoft Edge — браузер по умолчанию для Windows 10 — с бесплатными инструментами на dev.modern.IE :

Глубокие технические знания по Microsoft Edge и веб-платформе от наших инженеров и евангелистов:

Больше бесплатных кроссплатформенных инструментов и ресурсов для веб-платформы: