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);
正如您所看到的,我们使用了..``将一系列字符括起来,这被解释为字符串字面量,但是任何形式为${..}
的表达式都会被解析并立即内联评估。
插入式字符串字面量的一个非常好的好处是它们允许跨越多行:
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 );
插值表达式
任何有效的表达式,包括函数调用、内联函数表达式调用甚至其他的插值字符串字面量
,都可以出现在插值字符串字面量的${...}
中。
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 );
在这里,内部的 ${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();
使用模板字面量
来编写HTML代码,可以通过减少烦琐的操作使代码更易读。
传统方式:
'<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>`
- 字符串可以跨越多行。
- 您不必转义引号字符。
- 您可以避免像'">'这样的组合。
- 您不必使用加号运算符。
标记模板字面量
当一个template
字符串被标记时,它的literals
和替换项会被传递给一个函数,该函数返回结果值。
function myTaggedLiteral(strings) {
console.log(strings);
}
myTaggedLiteral`test`;
function myTaggedLiteral(strings,value,value2) {
console.log(strings,value, value2);
}
let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
我们可以在这里使用spread
运算符来传递多个值。第一个参数 - 我们称之为strings - 是所有纯字符串的数组(在任何插入表达式之间的内容)。
然后,我们使用...gather/rest操作符
将所有后续参数收集到名为values的数组中,尽管您当然可以像上面所做的那样将它们留作单独的命名参数跟在字符串参数后面(value1、value2等)
。
function myTaggedLiteral(strings,...values) {
console.log(strings);
console.log(values);
}
let someText = 'Neat';
myTaggedLiteral`test ${someText} ${2 + 3}`;
收集到值数组中的参数
是在字符串字面量中已经计算过的插值表达式的结果。 标记模板字符串
类似于插值计算后,但在编译最终字符串值之前的处理步骤,允许您更多地控制从字面量生成字符串。 让我们看一个创建可重复使用的模板
的示例。
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);
原始字符串
我们的标记函数接收一个名为 strings
的第一个参数,它是一个 数组
。但还有一个额外的数据包含在内:所有字符串的原始未处理版本。你可以使用 .raw
属性访问这些原始字符串值,像这样:
function showraw(strings, ...values) {
console.log( strings );
console.log( strings.raw );
}
showraw`Hello\nWorld`;
正如您所看到的,字符串的raw
版本保留了转义的 \n 序列,而处理后的字符串将其视为未转义的真实换行符。ES6带有一个内置函数,可用作字符串字面值标记:String.raw(..)
。它只是传递了strings
的原始版本:
console.log( `Hello\nWorld` );
console.log( String.raw`Hello\nWorld` );
// "Hello\nWorld"
tpl === MyVar
吗?唯一的区别在于它们创建时的语法不同。需要注意的是,与字符串拼接不同,模板提供了标签函数,可用于自动转义等功能。 - Bergi