ES6模板Literals V串联的string

我有以下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. 

这是小提琴。 我试图寻找确切的差异,但无法find它,我的问题是这两个声明有什么区别,

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

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

我已经能够在这里得到与person.name连接的stringMyVar ,那么使用模板文字将是什么情况?

如果您在问题示例中仅使用带有占位符(例如${expression} )的模板文字,则结果与仅连接string相同。 主观上它看起来更好,更容易阅读,特别是对于包含'"多行string或string,因为您不必再​​转义那些字符。

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

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

在本例的第二行中,调用了一个名为tag的函数。 模板string的内容被分割为多个variables,您可以在tag函数的参数中访问:文字部分(在本例中, My name is和)以及replace( John Smith )。 模板文字将被评估为任何tag函数返回。

ECMAScript wiki列出了一些用例,比如自动转义或编码input或本地化。 您可以创build一个名为msg的标记函数,它查找像“ My name is这样的文字部分,并将其replace为当前语言环境的语言,例如德语:

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

标记函数返回的值甚至不必是一个string。 这个查询select器示例应该返回一个DOM节点的集合:

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

ES6提出了一种新的string文字,使用\ back-tick`作为分隔符。 这些文字允许embedded基本的string插值expression式,然后自动分析和评估。

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

正如您所看到的,我们在一系列字符周围使用了..“,这些字符被解释为一个string字面值,但是${..}forms的任何expression式都将立即被内联parsing和计算。

内插string文字的一个很好的好处是它们可以分割成多行:

 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! 

插值expression式

任何有效的expression式都允许以${..}出现在插入的string中,包括函数调用,内联函数expression式调用,甚至是其他内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! 

在这里,当将whovariables与"s"string相结合,而不是who +“s”时,内部\ $ {who} s插入的string文字对我们来说有点更方便。 另外要注意的是插入的string文字只是在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!" 

通过减less烦恼,使用HTML的template literal显然更具可读性。

古老的方式:

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

使用ES6

 `<div class="${className}"> <p>${content}</p> <a href="${link}">Let's go</a> </div>` 
  • 你的string可以跨越多行。
  • 你不必逃避引号字符。
  • 你可以避免这样的分组:'>''
  • 您不必使用加号运算符。

标记模板文字

我们也可以标记一个templatestring,当templatestring被标记时, literals和replace被传递给返回结果值的函数。

 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运算符来传递多个值。 第一个参数 – 我们称之为string – 是所有普通string(任何插值expression式之间的东西)的数组。

然后我们把所有后续的参数收集到一个名为values的数组中,使用... gather/rest operator ,虽然你当然可以把它们作为单独的命名参数放在string参数之后,就像我们上面所做的那样(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)是在string文字中find的已经评估的插值expression式的结果。 带tagged string literal就像在插值计算之后,但在最终的string值被编译之前的一个处理步骤,允许您更多地控制从文字中生成string。 我们来看一个创build可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); 

原始的string

我们的标签函数接收我们称为strings的第一个参数,这是一个array 。 但是还有一些额外的数据:所有string的原始未处理版本。 您可以使用.raw属性访问这些原始string值,如下所示:

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

正如你所看到的,string的raw版本保留转义的\ n序列,而string的处理版本把它当作一个非转义的真正的新行。 ES6带有一个内置函数,可以用作string文字标签: String.raw(..) 。 它只是传递strings的原始版本:

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

这是一个更清洁,正如评论所述,是另一种语言的共同特点。 另一件我发现很好的是换行符,在编写string时非常有用。

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