ES6模板文字与连接字符串。

时间:2021-12-05 00:06:17

I have the following code for Ecma-Script-6 template literals

对于Ecma-Script-6模板文本,我有以下代码

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);

The output is as follows:

输出如下:

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

this is the fiddle. I tried searching for the exact difference but couldn't find it, My question is what is the difference between these two statements,

这是小提琴。我试着去寻找确切的区别但是没找到,我的问题是这两个表述的区别是什么,

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

And

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

I am already able to get the string MyVar concatenated with person.name here, so what would be the scenario to use the template literal ?

我已经能够将字符串MyVar与person.name连接在一起,那么使用模板文本的场景是什么呢?

3 个解决方案

#1


49  

If you are using template literals only with placeholders (e.g. ${expression}) like in the question's example, then the result is the same as just concatenating strings. Subjectively it looks better and is easier to read, especially for multi-line strings or strings containing both ' and " since you don't have to escape those characters any more.

如果您只使用模板文字和占位符(例如${expression}),就像在问题的示例中那样,那么结果与连接字符串是一样的。从主观上看,它看起来更好看,也更容易读,特别是对于包含'和'的多行字符串或字符串,因为您不再需要转义这些字符。

Readability is a great feature, but the most interesting thing about templates are Tagged template literals:

可读性是一个很好的特性,但是关于模板最有趣的事情是标记模板文字:

let person = {name: 'John Smith'};   
tag `My name is ${person.name}.`

In the second line of this example, a function named tag is called. The content of the template string is split into multiple variables, that you can access in the arguments of the tag function: literal sections (in this example My name is and .) and substitutions (John Smith). The template literal will be evaluated to whatever the tag function returns.

在本例的第二行中,调用一个名为tag的函数。模板字符串的内容被分割成多个变量,您可以在标记函数的参数中访问:文字部分(在本例中,我的名字是and .)和替换(John Smith)。模板文本将被计算到标记函数返回的任何值。

The ECMAScript wiki lists some use cases, like automatically escaping or encoding input, or localization. You could create a tag function named msg that looks up the literal parts like My name is and substitutes them with translations into the current locale's language, for example into German:

ECMAScript wiki列出了一些用例,比如自动转义或编码输入或本地化。您可以创建一个名为msg的标记函数,该函数查找像我的名字这样的文字部分,并将它们替换为当前语言环境的语言,例如德语:

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

The value returned by the tag function doesn't even have to be a string. This query selector example is supposed to return a collection of DOM nodes:

标记函数返回的值甚至不一定是字符串。这个查询选择器示例应该返回DOM节点的集合:

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

#2


8  

ES6 comes up with a new type of string literal, using the \ back-tick` as the delimiter. These literals do allow basic string interpolation expressions to be embedded, which are then automatically parsed and evaluated.

ES6提供了一种新的字符串文本类型,使用\后勾'作为分隔符。这些文本允许嵌入基本的字符串插补表达式,然后自动解析和计算这些表达式。

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);

As you can see, we used the ..`` around a series of characters, which are interpreted as a string literal, but any expressions of the form ${..} are parsed and evaluated inline immediately.

如你所见,我们使用。' ' '围绕一系列字符,这些字符被解释为字符串文字,但任何形式${..}立即进行内联解析和求值。

One really nice benefit of interpolated string literals is they are allowed to split across multiple lines:

插值字符串的一个很好的好处是它们可以被分割成多行:

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!

Interpolated Expressions

插值表达式

Any valid expression is allowed to appear inside ${..} in an interpolated string lit‐ eral, including function calls, inline function expression calls, and even other interpo‐ lated string literals!

任何有效的表达式都允许出现在${..在一个插入的字符串点亮‐eral中,包括函数调用、内联函数表达式调用,甚至其他插入的字符串文字!

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!

Here, the inner \${who}s`` interpolated string literal was a little bit nicer convenience for us when combining the who variable with the "s" string, as opposed to who + "s". Also to keep an note is an interpolated string literal is just lexically scoped where it appears, not dynamically scoped in any way

在这里,当将who变量与s字符串组合在一起时,内部的${who} ' s的内插字符串文字对我们来说更加方便,而不是who + s。同样要注意的是,内插字符串字面量只是在出现时的词法范围内,而不是以任何方式的动态范围内

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

Using the template literal for the HTML is definitely more readable by reducing the annoyance.

通过减少麻烦,为HTML使用模板文本无疑更容易阅读。

The plain old way:

普通的方式:

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

With ES6:

ES6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
  • Your string can span multiple lines.
  • 您的字符串可以跨多行。
  • You don't have to escape quotation characters.
  • 你不必转义引号。
  • You can avoid groupings like: '">'
  • 您可以避免以下分组:“>”
  • You don't have to use the plus operator.
  • 你不需要使用+运算符。

Tagged Template Literals

标记的模板文字

We can also tag a template string, when a template string is tagged, the literals and substitutions are passed to function which returns the resulting value.

我们还可以标记一个模板字符串,当一个模板字符串被标记时,文字和替换被传递给函数,该函数返回结果的值。

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

We can use the spread operator here to pass multiple values. The first argument — we called it strings — is an array of all the plain strings (the stuff between any interpolated expressions).

我们可以使用扩展运算符来传递多个值。第一个参数——我们称之为string——是所有纯字符串(任何内插表达式之间的东西)的数组。

we then gather up all subsequent arguments into an array called values using the ... gather/rest operator, though you could of course have left them as individual named parameters following the strings parameter like we did above (value1, value2 etc).

然后,我们将所有后续的参数收集到一个名为values的数组中,使用…gather/rest操作符,尽管您当然可以将它们作为单独的命名参数保留在string参数后面,就像我们上面所做的(value1, value2等)。

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

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

The argument(s) gathered into our values array are the results of the already evaluated interpolation expressions found in the string literal. A tagged string literal is like a processing step after the interpolations are evaluated but before the final string value is compiled, allowing you more control over generating the string from the literal. Let's look at an example of creating a 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);

Raw Strings

原始字符串

our tag functions receive a first argument we called strings, which is an array. But there’s an additional bit of data included: the raw unprocessed versions of all the strings. You can access those raw string values using the .raw property, like this:

我们的标记函数接收第一个参数,我们称之为字符串,它是一个数组。但是还包含另外一点数据:所有字符串的原始未处理版本。您可以使用.raw属性访问这些原始字符串值:

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

As you can see, the raw version of the string preserves the escaped \n sequence, while the processed version of the string treats it like an unescaped real new-line. ES6 comes with a built-in function that can be used as a string literal tag: String.raw(..). It simply passes through the raw versions of the strings:

正如您所看到的,该字符串的原始版本保存了转义的\n序列,而处理过的字符串则将其视为未脱逃的真正的新行。ES6附带了一个内置函数,可以用作字符串文字标记:string .raw(.. .)。它简单地遍历字符串的原始版本:

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

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

#3


4  

It's a lot cleaner and as stated in the comments, is a common features in another languages. The other thing that I found nice was the line breaks, very useful when writing strings.

它非常干净,并且在评论中声明,是另一种语言的共同特征。另一件我觉得不错的事情是换行,在写字符串时非常有用。

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);

#1


49  

If you are using template literals only with placeholders (e.g. ${expression}) like in the question's example, then the result is the same as just concatenating strings. Subjectively it looks better and is easier to read, especially for multi-line strings or strings containing both ' and " since you don't have to escape those characters any more.

如果您只使用模板文字和占位符(例如${expression}),就像在问题的示例中那样,那么结果与连接字符串是一样的。从主观上看,它看起来更好看,也更容易读,特别是对于包含'和'的多行字符串或字符串,因为您不再需要转义这些字符。

Readability is a great feature, but the most interesting thing about templates are Tagged template literals:

可读性是一个很好的特性,但是关于模板最有趣的事情是标记模板文字:

let person = {name: 'John Smith'};   
tag `My name is ${person.name}.`

In the second line of this example, a function named tag is called. The content of the template string is split into multiple variables, that you can access in the arguments of the tag function: literal sections (in this example My name is and .) and substitutions (John Smith). The template literal will be evaluated to whatever the tag function returns.

在本例的第二行中,调用一个名为tag的函数。模板字符串的内容被分割成多个变量,您可以在标记函数的参数中访问:文字部分(在本例中,我的名字是and .)和替换(John Smith)。模板文本将被计算到标记函数返回的任何值。

The ECMAScript wiki lists some use cases, like automatically escaping or encoding input, or localization. You could create a tag function named msg that looks up the literal parts like My name is and substitutes them with translations into the current locale's language, for example into German:

ECMAScript wiki列出了一些用例,比如自动转义或编码输入或本地化。您可以创建一个名为msg的标记函数,该函数查找像我的名字这样的文字部分,并将它们替换为当前语言环境的语言,例如德语:

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

The value returned by the tag function doesn't even have to be a string. This query selector example is supposed to return a collection of DOM nodes:

标记函数返回的值甚至不一定是字符串。这个查询选择器示例应该返回DOM节点的集合:

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

#2


8  

ES6 comes up with a new type of string literal, using the \ back-tick` as the delimiter. These literals do allow basic string interpolation expressions to be embedded, which are then automatically parsed and evaluated.

ES6提供了一种新的字符串文本类型,使用\后勾'作为分隔符。这些文本允许嵌入基本的字符串插补表达式,然后自动解析和计算这些表达式。

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);

As you can see, we used the ..`` around a series of characters, which are interpreted as a string literal, but any expressions of the form ${..} are parsed and evaluated inline immediately.

如你所见,我们使用。' ' '围绕一系列字符,这些字符被解释为字符串文字,但任何形式${..}立即进行内联解析和求值。

One really nice benefit of interpolated string literals is they are allowed to split across multiple lines:

插值字符串的一个很好的好处是它们可以被分割成多行:

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!

Interpolated Expressions

插值表达式

Any valid expression is allowed to appear inside ${..} in an interpolated string lit‐ eral, including function calls, inline function expression calls, and even other interpo‐ lated string literals!

任何有效的表达式都允许出现在${..在一个插入的字符串点亮‐eral中,包括函数调用、内联函数表达式调用,甚至其他插入的字符串文字!

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!

Here, the inner \${who}s`` interpolated string literal was a little bit nicer convenience for us when combining the who variable with the "s" string, as opposed to who + "s". Also to keep an note is an interpolated string literal is just lexically scoped where it appears, not dynamically scoped in any way

在这里,当将who变量与s字符串组合在一起时,内部的${who} ' s的内插字符串文字对我们来说更加方便,而不是who + s。同样要注意的是,内插字符串字面量只是在出现时的词法范围内,而不是以任何方式的动态范围内

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

Using the template literal for the HTML is definitely more readable by reducing the annoyance.

通过减少麻烦,为HTML使用模板文本无疑更容易阅读。

The plain old way:

普通的方式:

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

With ES6:

ES6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
  • Your string can span multiple lines.
  • 您的字符串可以跨多行。
  • You don't have to escape quotation characters.
  • 你不必转义引号。
  • You can avoid groupings like: '">'
  • 您可以避免以下分组:“>”
  • You don't have to use the plus operator.
  • 你不需要使用+运算符。

Tagged Template Literals

标记的模板文字

We can also tag a template string, when a template string is tagged, the literals and substitutions are passed to function which returns the resulting value.

我们还可以标记一个模板字符串,当一个模板字符串被标记时,文字和替换被传递给函数,该函数返回结果的值。

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

We can use the spread operator here to pass multiple values. The first argument — we called it strings — is an array of all the plain strings (the stuff between any interpolated expressions).

我们可以使用扩展运算符来传递多个值。第一个参数——我们称之为string——是所有纯字符串(任何内插表达式之间的东西)的数组。

we then gather up all subsequent arguments into an array called values using the ... gather/rest operator, though you could of course have left them as individual named parameters following the strings parameter like we did above (value1, value2 etc).

然后,我们将所有后续的参数收集到一个名为values的数组中,使用…gather/rest操作符,尽管您当然可以将它们作为单独的命名参数保留在string参数后面,就像我们上面所做的(value1, value2等)。

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

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

The argument(s) gathered into our values array are the results of the already evaluated interpolation expressions found in the string literal. A tagged string literal is like a processing step after the interpolations are evaluated but before the final string value is compiled, allowing you more control over generating the string from the literal. Let's look at an example of creating a 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);

Raw Strings

原始字符串

our tag functions receive a first argument we called strings, which is an array. But there’s an additional bit of data included: the raw unprocessed versions of all the strings. You can access those raw string values using the .raw property, like this:

我们的标记函数接收第一个参数,我们称之为字符串,它是一个数组。但是还包含另外一点数据:所有字符串的原始未处理版本。您可以使用.raw属性访问这些原始字符串值:

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

As you can see, the raw version of the string preserves the escaped \n sequence, while the processed version of the string treats it like an unescaped real new-line. ES6 comes with a built-in function that can be used as a string literal tag: String.raw(..). It simply passes through the raw versions of the strings:

正如您所看到的,该字符串的原始版本保存了转义的\n序列,而处理过的字符串则将其视为未脱逃的真正的新行。ES6附带了一个内置函数,可以用作字符串文字标记:string .raw(.. .)。它简单地遍历字符串的原始版本:

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

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

#3


4  

It's a lot cleaner and as stated in the comments, is a common features in another languages. The other thing that I found nice was the line breaks, very useful when writing strings.

它非常干净,并且在评论中声明,是另一种语言的共同特征。另一件我觉得不错的事情是换行,在写字符串时非常有用。

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);