ECMAScript 6 提出了一种新类型的字符串文字,使用反引号作为分隔符。这些文字确实允许嵌入基本的字符串插值表达式,然后自动解析和评估。
let person = {name: 'RajiniKanth', age: 68, greeting: 'Thalaivaaaa!' };
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);
如您所见,我们在一系列字符周围使用了`,这些字符被解释为字符串文字,但${..} 形式的任何表达式都会立即内联解析和求值。
内插字符串字面量的一个非常好的好处是它们可以分成多行:
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 like RajiniKanth
// to come to the aid of their
// country!
插值表达式
任何有效的表达式都可以出现在${..} 内插字符串文字中,包括函数调用、内联函数表达式调用,甚至其他内插字符串文字!
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` 内插字符串文字对我们来说更方便一些。另外要注意的是,插入的字符串文字只是在其出现的地方进行词法作用域,而不是以任何方式动态作用域:
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!"
为 HTML 使用模板字面量肯定会通过减少烦恼而更具可读性。
简单的老方法:
'<div class="' + className + '">' +
'<p>' + content + '</p>' +
'<a href="' + link + '">Let\'s go</a>'
'</div>';
使用 ECMAScript 6:
`<div class="${className}">
<p>${content}</p>
<a href="${link}">Let's go</a>
</div>`
- 您的字符串可以跨越多行。
- 您不必转义引号字符。
- 您可以避免这样的分组:'">'
- 您不必使用加号运算符。
标记的模板文字
我们也可以标记一个模板字符串,当一个模板字符串被标记时,文字和替换被传递给返回结果值的函数。
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
我们可以在这里使用扩展运算符来传递多个值。第一个参数——我们称之为字符串——是一个包含所有普通字符串的数组(任何插值表达式之间的东西)。
然后,我们使用... gather/rest operator 将所有后续参数收集到一个名为 values 的数组中,尽管您当然可以像我们上面所做的那样将它们作为单独的命名参数留在字符串参数之后(value1、value2、等等)。
function myTaggedLiteral(strings, ...values) {
console.log(strings);
console.log(values);
}
let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
//["test", ""]
// "Neat"
// 5
收集到我们的 values 数组中的参数是在字符串文字中找到的已经评估的插值表达式的结果。标记字符串文字就像插值计算之后但在最终字符串值编译之前的处理步骤,允许您更好地控制从文字生成字符串。让我们看一个创建可重用模板的示例。
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 属性访问这些原始字符串值,如下所示:
function showraw(strings, ...values) {
console.log(strings);
console.log(strings.raw);
}
showraw`Hello\nWorld`;
如您所见,字符串的原始版本保留了转义的\n 序列,而字符串的处理版本将其视为未转义的真正换行符。 ECMAScript 6 带有一个可用作字符串文字标签的内置函数:String.raw(..)。它只是通过字符串的原始版本:
console.log(`Hello\nWorld`);
/* "Hello
World" */
console.log(String.raw`Hello\nWorld`);
// "Hello\nWorld"