В рамках изучения нового стандарта наткнулся на Tagged Template Literals, по русски часто обзывают строковые шаблоны.
За рубежом советуют переименовать в tagged string literals, а Template Literals тем временем в interpolated string literals или просто interpoliterals . Обожаю js тусовку, где халивар начинают даже из за название фичи 🙂
Что, куда, зачем
Прежде чем перейдем не посредственно к тому о чем я хотел рассказать из ходя из заголовка, пару слов о Template Literals.
Наверняка каждый из вас их уже попробовал:
var text = `Now is the time for all good men to come to the aid of their country!`; console.log( text ); // Now is the time for all good men // to come to the aid of their // country!
Первая их крутость, заключается в том, что текст такого литерала можно писать на нескольких строчках и он сам где надо вставит переход на новую строку.
Конечно же вторая крутость заключается в возможности вставки выражении в литерал, что значительно упрощает построение строк в которые вы хотите вставить какое либо значение.
До ES6:
var name = "Kyle"; var greeting = "Hello " + name + "!"; console.log( greeting ); // "Hello Kyle!" console.log( typeof greeting ); // "string"
Решение проблемы с помощью Template Literals:
var name = "Kyle"; var greeting = `Hello ${name}!`; console.log( greeting ); // "Hello Kyle!" console.log( typeof greeting ); // "string"
Тут конечно надо заметить, что переиспользовать данный литерал с другим значением нельзя. По этому ходят споры об именовании. Куда было бы разумней назвать не используя слово шаблон, а интерполяция, что бы не вводить в заблуждение. Данный литерал подобен Immediately-Invoked Function Expression (IIFE), он сразу же запекается в строку. По этому передать его и переиспользовать к сожалению возможности нет:
function foo(str) { var name = "foo"; console.log( str ); //name уже давно в str и str typeof 'string' } function bar() { var name = "bar"; foo( `Hello from ${name}!` ); } var name = "global"; bar();
Как я писал выше, вставить в строку можно и результат выражения:
function upper(s) { return s.toUpperCase(); } var who = "reader"; var text = `A very ${upper( "warm" )} welcome to all of you ${upper( `${who}s` )}!`; console.log( text ); // A very WARM welcome // to all of you READERS!
Tagged Template Literals
А теперь самое интересное, рассмотрим с вами использование Tagged Template Literals:
function foo(strings, ...values) { console.log( strings ); console.log( values ); } var desc = "awesome"; foo`Everything is ${desc}!`; // [ "Everything is ", "!"] // [ "awesome" ]
В данном случае tag foo
, своего рода вызов функции без (...)
. Таким образом, мы можем обработать строку дополнительно.
В качестве аргументов, функция foo
получает массив строк, которые были вокруг выражения ${desk}
, и собственно сами значения выражений.
С помощью такого сахарного синтаксиса, очень просто представить себе перевод строк:
const greeting = lang`Hello ${ name }!`
Как по мне куда проще нежели — учитывая, что в строке есть динамические данные:
const greeting = `${ lang('Hello') } ${ name }!`
Или совсем сносный пример который можно часто увидеть:
const greeting = lang('Hello') + name + '!';
Так как мы получаем в функции по факту разобранную строку на части, нам придется ее самим собрать, с этим нам поможет reduce:
function lang(strings, ...values) { return strings.reduce( function(s,v,idx){ return s + (idx > 0 ? values[idx-1] : "") + v; }, "" ); }
Добавим вызов функции перевода и сделаем пример чуть более читабельным, получив вот такой сниппет:
const lang = l = (strings, ...values) => strings.reduce((prevString, nextString, index) => prevString + (index > 0 ? values[index - 1] : '') + translate(nextString), ''); //Реализация функции translate в ваших руках :)
Использование:
const name = 'Дмитрий'; console.log( lang`Hello ${ name }, how are you?` ) //Или сокращенный console.log( l`Hello ${ name }, how are you?` ) //Привет Дмитрий, как дела?
Еще один очень полезный пример перевода чисел в формат US $:
function dollabillsyall(strings, ...values) { return strings.reduce( function(s,v,idx){ if (idx > 0) { if (typeof values[idx-1] == "number") { // look, also using interpolated // string literals! s += `$${values[idx-1].toFixed( 2 )}`; } else { s += values[idx-1]; } } return s + v; }, "" ); } var amt1 = 11.99, amt2 = amt1 * 1.08, name = "Kyle"; var text = dollabillsyall `Thanks for your purchase, ${name}! Your product cost was ${amt1}, which with tax comes out to ${amt2}.` console.log( text ); // Thanks for your purchase, Kyle! Your // product cost was $11.99, which with tax // comes out to $12.95.
Собственно говоря у пост обработки строк Tagged Template Literals есть и другие применения, но это уже за рамками темы, пишите в комментариях если есть, что добавить 🙂
Источник вдохновения:
github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch2.md
ссылка на оригинал статьи https://habrahabr.ru/post/279595/
Добавить комментарий