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可以跨越多行。
- 你不必逃避引号字符。
- 你可以避免这样的分组:'>''
- 您不必使用加号运算符。
标记模板文字
我们也可以标记一个template
string,当template
string被标记时, 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);