Template literals (aka. template strings) 是 ES2015 提出的语法特性,方便了字符串拼接。
基础:
`string text`
多行字符串:
`string text line 1
string text line 2`
模板:
`string text ${expression} string text`
Tagged templates:
tag`string text ${expression} string text`
其中 tagged templates 是比较复杂的。它设计之初是希望 tag 函数可以拿到 template string 中的信息,比如它有几段字符串、有哪些表达式,从而可以做一些加工或者逻辑,再返回加工后的信息。这是 MDN 的一个例子:
let person = 'Mike';
let age = 28;
function myTag(strings, personExp, ageExp) {
let str0 = strings[0]; // "That "
let str1 = strings[1]; // " is a "
// There is technically a string after
// the final expression (in our example),
// but it is empty (""), so disregard.
// let str2 = strings[2];
let ageStr;
if (ageExp > 99){
ageStr = 'centenarian';
} else {
ageStr = 'youngster';
}
// We can even return a string built using a template literal
return `${str0}${personExp}${str1}${ageStr}`;
}
let output = myTag`That ${ person } is a ${ age }`;
console.log(output);
// That Mike is a youngster
另外一个例子,配合使用 Spread Operator:
function tag(strings, ...values) {
console.log(strings);
console.log(values);
return 'whatever';
}
let a = 1;
let b = 2;
tag`a = ${a}, b = ${b}`
// Output:
// ["a = ", ", b = ", ""]
// [1, 2]
注意 strings
中会带有最后的空字符串。一般没什么用处。strings
中还会有一个 raw
属性,返回未 escaped 的原字符串(比如 \n
这些)。
对于业界在 tagged template 上的实际使用,有 styled-components 中 大量使用 它来 扩展 API 能力:
const mixin = css`...`
styled.div`
/* this function would just be toString()'d */
background: ${p => p.color || 'white'};
/* this mixin wouldn't be flattened into the rest of the rules */
${mixin}
`
如果没有 tagged template,上面例子中的 arrow function 会简单地被转成 string,styled-component 的 API 将无法拿到函数对象;同时它也无法拿到 mixin 做更复杂的处理。