ECMAScript 6新增了使用模板字面量定义字符串的能力。与使用单引号或双引号不同,模板字面量保留换行字符,可以跨行定义字符串:
let str1 = '早起的年轻人\n喜欢经常跳步';
let str2 = `早起的年轻人
喜欢经常跳步`;
console.log(str1);
// 早起的年轻人
// second line"
console.log(str2);
// 早起的年轻人
// 喜欢经常跳步
console.log(str1 === str2); // true
比定义HTML模板:
let pageHTML = `
<div>
<a href="#">
<span>早起的年轻人</span>
</a>
</div>`;
模板字符中会保持反引号内部的空格,因此在使用时要格外注意。
// 这个模板字面量在换行符之后有25 个空格符
let str1 = `first line
second line`;
console.log(str1.length); // 47
// 这个模板字面量以一个换行符开头
let str2 = `
first line
second line`;
console.log(str2[0] === '\n'); // true
支持字符串插值,也就是可以在一个连续定义中插入一个或多个值。
上述所描述的模板字面量是一种特殊的JavaScript句法表达式,只不过求值后得到的是字符串。模板字面量在定义时立即求值并转换为字符串实例,任何插入的变量也会从它们最接近的作用域中取值。
字符串插值通过在${}中使用一个JavaScript表达式实现:
let value =10;
let exponent = 'second';
// 以前
let str1 =
value + ' to the ' + exponent + ' power is ' + (value * value);
// 现在,可以用模板字面量这样实现: 反引号 `
let str2 =
`${ value } to the ${ exponent } power is ${ value * value }`;
console.log(str1); // 10 to the second power is 100
console.log(str2); // 10 to the second power is 100
所有插入的值都会使用toString()强制转型为字符串,而且任何JavaScript表达式都可以用于插值。嵌套的模板字符串无须转义:
console.log(`Hello, ${ `World` }! `); // Hello, World!
将表达式转换为字符串时会调用toString():
let foo = { toString: () => 'World' };
console.log(`Hello, ${ foo }! `);
在插值表达式中可以调用函数和方法:
function capitalize(word) {
return `${ word[0].toUpperCase() }${ word.slice(1) }`;
}
let str1 = `${ capitalize('hello') }, ${ capitalize('world') }! `;
console.log(str1); // Hello, World!
模板字面量也支持定义标签函数(tag function),而通过标签函数可以自定义插值行为。
let a = 10;
let b = 12;
function simpleTag(str1, str2, str3, str4) {
console.log(str1);
console.log(str2);
console.log(str3);
console.log(str4);
return '早起的年轻人';
}
let untaggedResult = `${ a } + ${ b } = ${ a + b }`;
let taggedResult=simpleTag`${a}+${b}=${a+b}`;
console.log(untaggedResult); // "10 + 12= 22"
console.log(taggedResult); // "早起的年轻人"
因为表达式参数的数量是可变的,所以通常应该使用剩余操作符:
let a = 6;
let b = 9;
functionsimpleTag(strings, ...expressions){
console.log(strings);
for(const expression of expressions) {
console.log(expression);
}
return '早起的年轻人';
}
let taggedResult = simpleTag`${ a } + ${ b } = ${ a + b }`;
console.log(taggedResult);
如果你想把这些字符串和对表达式求值的结果拼接起来作为默认返回的字符串,可以这样做:
let a = 6;
let b = 9;
function zipTag(strings, ...expressions) {
return strings[0] +
expressions.map((e, i) => `${e}${strings[i + 1]}`)
.join('');
}
let st1 = `${ a } + ${ b } = ${ a + b }`;
let st2 = zipTag`${ a } + ${ b } = ${ a + b }`;
console.log(st1); // "6 + 9 = 15"
console.log(st2); // "6 + 9 = 15"