Подтвердить что ты не робот

Литералы шаблонов ES6 и конкатенированные строки

У меня есть следующий код для Ecma- Script -6 template literals

let person = {name: 'John Smith'};   
let tpl = `My name is ${person.name}.`;    
let MyVar="My name is "+ person.name+".";

console.log("template literal= "+tpl);  
console.log("my variable = "+MyVar);

Выход выглядит следующим образом:

template literal= My name is John Smith.
my variable = My name is John Smith.

это является скрипкой. Я попытался найти точную разницу, но не смог ее найти, Мой вопрос в том, в чем разница между этими двумя утверждениями,

  let tpl = `My name is ${person.name}.`;    

и

  let MyVar = "My name is "+ person.name+".";

Я уже могу получить строку MyVar, сцепленную с person.name здесь, так что может быть сценарий для использования литерала шаблона?

4b9b3361

Ответ 1

Если вы используете шаблонные литералы только с заполнителями (например, 'Hello ${person.name}'), как в примере с вопросом, то результат такой же, как просто конкатенация строк. Субъективно это выглядит лучше и легче для чтения, особенно для многострочных строк или строк, содержащих оба ' и " поскольку вам больше не нужно экранировать эти символы.

Читаемость - отличная функция, но самое интересное в шаблонах - помеченные литералы шаблонов:

let person = {name: 'John Smith'}; 
let tag = (strArr, name) => strArr[0] + name.toUpperCase() + strArr[1];  
tag 'My name is ${person.name}!' // Output: My name is JOHN SMITH!

В третьей строке этого примера вызывается функция с именем tag. Содержимое строки шаблона разделено на несколько переменных, к которым вы можете обращаться в аргументах функции tag: литеральные разделы (в этом примере значение strArr[0] равно My name is а значение strArr[1] равно !) и замены (John Smith). Шаблонный литерал будет оцениваться в соответствии с тем, что возвращает функция tag.

В вики ECMAScript перечислены некоторые возможные варианты использования, такие как автоматическое экранирование или кодирование ввода или локализация. Вы можете создать функцию тега с именем msg которая ищет буквальные части, такие как " My name is и заменяет их переводами на текущий язык локали, например на немецкий:

console.log(msg'My name is ${person.name}.') // Output: Mein Name ist John Smith.

Значение, возвращаемое функцией tag, даже не должно быть строкой. Вы можете создать функцию тега с именем $ которая оценивает строку и использует ее как селектор запросов для возврата коллекции узлов DOM, как в этом примере:

$'a.${className}[href=~'//${domain}/']'

Ответ 2

ES6 появляется новый тип строкового литерала, используя \ back-tick` в качестве разделителя. Эти литералы позволяют встроить встроенные интерполяционные выражения, которые затем автоматически анализируются и оцениваются.

let actor = {name: 'RajiniKanth', age: 68};

let oldWayStr = "<p>My name is " + actor.name + ",</p>\n" +
  "<p>I am " + actor.age + " old</p>\n";

let newWayHtmlStr =
 `<p>My name is ${actor.name},</p>
  <p>I am ${actor.age} old</p>`;

console.log(oldWayStr);
console.log(newWayHtmlStr);

Как вы можете видеть, мы использовали... `` вокруг ряда символов, которые интерпретируются как строковый литерал, но любые выражения формы ${..} анализируются и сразу вычисляются inline.

Одно действительно приятное преимущество интерполированных строковых литералов - разрешено разделять на несколько строк:

var Actor = {"name" : "RajiniKanth"};

var text =
`Now is the time for all good men like ${Actor.name}
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!

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

Любое допустимое выражение разрешено появляться внутри ${..} в интерполированной строке lit‐ eral, включая вызовы функций, вызовы выражения встроенной функции и даже другие interpo‐ lated string literals!

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!

Здесь внутренний интерполяционный строковый литерал \who\s`` был немного приятнее для нас при объединении переменной who с строкой "s", в отличие от who + "s". Также, чтобы сохранить примечание, интерполированный строковый литерал просто lexically scoped, где он появляется, а не dynamically scoped каким-либо образом

function foo(str) {
 var name = "foo";
 console.log( str );
}
function bar() {
 var name = "bar";
 foo( `Hello from ${name}!` );
}
var name = "global";
bar(); // "Hello from bar!"

Использование template literal для HTML определенно более читаемо, уменьшая раздражение.

Простой старый способ:

'<div class="' + className + '">' +
  '<p>' + content + '</p>' +
  '<a href="' + link + '">Let\ go</a>'
'</div>';

С ES6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let go</a>
</div>`
  • Ваша строка может охватывать несколько строк.
  • Вам не нужно скрывать символы котировки.
  • Вы можете избежать группировок, таких как: '" > '
  • Вам не нужно использовать оператор plus.

Литералы с метками шаблонов

Мы также можем пометить строку template, когда тега template отмечена, literals и подстановки передаются функции, которая возвращает результирующее значение.

function myTaggedLiteral(strings) {
  console.log(strings);
}

myTaggedLiteral`test`; //["test"]

function myTaggedLiteral(strings,value,value2) {
  console.log(strings,value, value2);
}
let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

Мы можем использовать оператор spread здесь, чтобы передать несколько значений. Первый аргумент - мы называем его строками - это массив всех простых строк (материал между любыми интерполированными выражениями).

мы собираем все последующие аргументы в массив, называемый значениями с помощью ... gather/rest operator, хотя вы, конечно, могли бы оставить их как индивидуальные именованные параметры, следуя параметру строк, как мы делали выше (value1, value2 etc).

function myTaggedLiteral(strings,...values) {
  console.log(strings);
  console.log(values);    
}

let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5

argument(s), собранный в нашем массиве значений, является результатом уже оцененных интерполяционных выражений, найденных в строковом литерале. A tagged string literal - это как шаг обработки после вычисления интерполяций, но до компиляции окончательного строкового значения, что позволяет вам более эффективно управлять строкой из литерала. Рассмотрим пример создания re-usable templates.

const Actor = {
  name: "RajiniKanth",
  store: "Landmark"
}

const ActorTemplate = templater`<article>
  <h3>${'name'} is a Actor</h3>
  <p>You can find his movies at ${'store'}.</p>

</article>`;

function templater(strings, ...keys) {
  return function(data) {
  let temp = strings.slice();
  keys.forEach((key, i) => {
  temp[i] = temp[i] + data[key];
  });
  return temp.join('');
  }
};

const myTemplate = ActorTemplate(Actor);
console.log(myTemplate);

Необработанные строки

наши функции тега получают первый аргумент, который мы назвали strings, который является array. Но в них добавлен еще один бит данных: необработанные необработанные версии всех строк. Вы можете получить доступ к этим исходным строковым значениям с помощью свойства .raw, например:

function showraw(strings, ...values) {
 console.log( strings );
 console.log( strings.raw );
}
showraw`Hello\nWorld`;

Как вы можете видеть, версия строки raw сохраняет сохраненную последовательность \n, в то время как обработанная версия этой строки относится к ней как к незанятой реальной новой строке. ES6 поставляется со встроенной функцией, которая может использоваться как тег строкового литерала: String.raw(..). Он просто проходит через исходные версии strings:

console.log( `Hello\nWorld` );
/* "Hello
World" */

console.log( String.raw`Hello\nWorld` );
// "Hello\nWorld"

Ответ 3

Это намного чище и, как указано в комментариях, является распространенным явлением на других языках. Другая вещь, которую я нашел приятной, - это разрывы строк, очень полезные при написании строк.

let person = {name: 'John Smith', age: 24, greeting: 'Cool!' };

let usualHtmlStr = "<p>My name is " + person.name + ",</p>\n" +
                   "<p>I am " + person.age + " old</p>\n" +
                   "<strong>\"" + person.greeting +"\" is what I usually say</strong>";


let newHtmlStr = 
 `<p>My name is ${person.name},</p>
  <p>I am ${person.age} old</p>
  <p>"${person.greeting}" is what I usually say</strong>`;


console.log(usualHtmlStr);
console.log(newHtmlStr);

Ответ 4

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

Допустим, у меня есть

let patient1 = {firstName: "John", lastName: "Smith"};
let patient2 = {firstName: "Dwayne", lastName: "Johnson", middleName: "'The Rock'"};

Таким образом, у некоторых пациентов есть middleName, а у других - нет.

Если бы я хотел строку, представляющую полное имя пациента

let patientName = '${patient1.firstName} ${patient1.middleName} ${patient1.lastName}';

Тогда это станет "Джон неопределенный Смит"

Однако если бы я сделал

let patientName = [patient1.firstName, patient1.middleName,  patient1.lastName].join(" ");

Тогда это станет просто "Джон Смит"

РЕДАКТИРОВАТЬ

General_Twyckenham указал, что соединение "" приведет к появлению дополнительного пробела между "John" и "Smith".

Чтобы обойти это, у вас может быть фильтр перед объединением, чтобы избавиться от ложных значений: [patient1.firstName, patient1.middleName, patient1.lastName].filter(el => el).join(" ");