ES6模板文字与串联字符串

Nae*_*ikh 64 javascript node.js ecmascript-6 template-strings

我有以下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);
Run Code Online (Sandbox Code Playgroud)

输出如下:

template literal= My name is John Smith.
my variable = My name is John Smith.
Run Code Online (Sandbox Code Playgroud)

是小提琴.我试着寻找确切的差异但找不到它,我的问题是这两个陈述有什么区别,

  let tpl = `My name is ${person.name}.`;    
Run Code Online (Sandbox Code Playgroud)

  let MyVar = "My name is "+ person.name+".";
Run Code Online (Sandbox Code Playgroud)

我已经能够在这里MyVar连接字符串person.name了,那么使用模板文字的场景是什么?

kap*_*pex 84

如果你只使用模板文字和占位符(例如`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!
Run Code Online (Sandbox Code Playgroud)

在此示例的第三行中,tag调用了一个名为的函数.模板字符串的内容被分成多个变量,你可以在的参数访问tag功能:文字部分(在这个例子中strArr[0]My name is)和替换(strArr[1]).模板文字将被评估为!函数返回的任何内容.(在这种情况下)

ECMAScript的维基列出了一些可能的使用情况下,如自动转义或编码输入,或定位.您可以创建一个名为John Smith查找文字部分的标记函数,tag并将它们用翻译替换为当前语言环境的语言,例如替换为德语:

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

标记函数返回的值甚至不必是字符串.您可以创建一个名为tag的标记函数msg,该函数计算字符串并将其用作查询选择器以返回DOM节点的集合,如下例所示:

$`a.${className}[href=~'//${domain}/']`
Run Code Online (Sandbox Code Playgroud)

  • 太好了!如果你有另一个模板文字,比如$ {person.message},它会被翻译吗? (2认同)
  • @AniketSuryavanshi这是模板字符串与串联性能的比较:/sf/answers/2035842721/几年前,模板字符串速度较慢,但​​看起来比现在的串联速度要快一些。 (2认同)

Tha*_*var 15

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);
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我们在一系列字符周围使用了..``,这些字符被解释为字符串文字,但是表格的任何表达式都会${..}被立即解析和评估.

插值字符串文字的一个非常好的好处是允许它们分成多行:

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!
Run Code Online (Sandbox Code Playgroud)

插值表达式

任何有效的表达式都允许出现${..}在插值字符串中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!
Run Code Online (Sandbox Code Playgroud)

在这里,内部\ $ {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!"
Run Code Online (Sandbox Code Playgroud)

template literal通过减少烦恼,使用for HTML肯定更具可读性.

简单的旧方式:

'<div class="' + className + '">' +
  '<p>' + content + '</p>' +
  '<a href="' + link + '">Let\'s go</a>'
'</div>';
Run Code Online (Sandbox Code Playgroud)

ES6:

`<div class="${className}">
  <p>${content}</p>
  <a href="${link}">Let's go</a>
</div>`
Run Code Online (Sandbox Code Playgroud)
  • 您的字符串可以跨越多行.
  • 您不必转义引号字符.
  • 您可以避免分组:"">
  • 您不必使用加号运算符.

标记模板文字

我们还可以标记一个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
Run Code Online (Sandbox Code Playgroud)

我们可以在spread这里使用运算符来传递多个值.第一个参数 - 我们称之为字符串 - 是一个包含所有普通字符串的数组(任何插值表达式之间的东西).

然后我们使用the将所有后续参数收集到一个名为values的数组中... gather/rest operator,尽管你可以将它们作为单独的命名参数留在strings参数之后,就像我们上面所做的那样(value1, value2 etc).

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

let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

原始字符串

我们的标记函数接收我们调用的第一个参数strings,它是一个array.但是还有一些数据包括:所有字符串的原始未处理版本.您可以使用.raw属性访问这些原始字符串值,如下所示:

function showraw(strings, ...values) {
 console.log( strings );
 console.log( strings.raw );
}
showraw`Hello\nWorld`;
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,raw字符串的版本保留了转义的\n序列,而字符串的处理版本将其视为未转义的真实换行符. ES6附带内置函数,可用作字符串文字标记: String.raw(..).它只是通过以下原始版本strings:

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

console.log( String.raw`Hello\nWorld` );
// "Hello\nWorld"
Run Code Online (Sandbox Code Playgroud)


Rig*_*tti 6

正如评论中所述,它更清晰,是其他语言的共同特征。我发现的另一件事是换行符,在编写字符串时非常有用。

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);
Run Code Online (Sandbox Code Playgroud)

  • @NaeemShaikh 我非常抱歉,但文字换行符确实有效。刚刚注意到 ES6Fiddle 只是一种糟糕的测试方式。我会编辑我的答案。 (2认同)

Dhr*_*ash 6

虽然我的回答没有直接解决这个问题,但我认为指出使用模板文字支持数组连接的一个缺点可能会很有趣。

\n

让\xe2\x80\x99s 说我有

\n
let patient1 = {firstName: "John", lastName: "Smith"};\nlet patient2 = {firstName: "Dwayne", lastName: "Johnson", middleName: "'The Rock'"};\n
Run Code Online (Sandbox Code Playgroud)\n

因此,有些患者有中间名,而另一些则没有。

\n

如果我想要一个代表患者全名的字符串

\n
let patientName = `${patient1.firstName} ${patient1.middleName} ${patient1.lastName}`;\n
Run Code Online (Sandbox Code Playgroud)\n

那么这将变成“John undefined Smith”

\n

但是如果我这样做了

\n
let patientName = [patient1.firstName, patient1.middleName,  patient1.lastName].join(" ");\n
Run Code Online (Sandbox Code Playgroud)\n

那么这将变成“约翰·史密斯”

\n

General_Twyckenham 指出“ ”上的连接会导致“John”和“Smith”之间出现额外的空格。

\n

为了解决这个问题,您可以在连接之前使用过滤器来消除虚假值:

\n
[patient1.firstName, patient1.middleName, patient1.lastName].filter(el => el).join(" ");\n
Run Code Online (Sandbox Code Playgroud)\n

  • 实际上,这并不完全正确 - “join”版本将为您提供 **John Smith**,并带有额外的空间。正如您可以想象的那样,这通常是不可取的。解决这个问题的方法是使用`map`,如下所示:`[patent1.firstName, Patient1.middleName, Patient1.lastName].map(el =&gt; el).join(" ");` (3认同)