模板字符串
模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。
它们在 ES2015 规范的先前版本中被称为“模板字符串”。
语法:
`string text`
`string text line 1
string text line 2`
`string text ${expression} string text`
tag `string text ${expression} string text`
模板字符串使用反引号 (` `
) 来代替普通字符串中的用双引号和单引号。
模板字符串可以包含特定语法(${expression}
)的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。
`\`` === "`" // --> true
带标签的模板字符串
更高级的形式的模板字符串是带标签的模板字符串。标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其余的参数与表达式相关。最后,你的函数可以返回处理好的的字符串。用于该标签的函数的名称可以被命名为任何名字。如下例:
function tag(strings, personExp, ageExp) {
let str0 = strings[0]; // 带
let str1 = strings[1]; // 的
let str2 = strings[2]; // 字符串。
return `${str0}${personExp}${str1}${ageExp}${str2}`;
}
let output = tag`带${ "标签" }的${ "模板" }字符串。`;
console.log(output); // '带标签的模板字符串。'
标签函数并不一定需要返回一个字符串:
function template(strings, ...keys) {
return (...values) => {
let result = [strings[0]];
keys.forEach((val, i) => {
result.push(values[val], strings[i+1])
})
return result.join('');
};
}
let t1 = template`${0}${1}${0}!`;
t1('A', 'I'); // 'AIA!'
let t2 = template`${0}${1} ${0}${1}`;
t2('咕', '噜'); // '咕噜 咕噜'
在标签函数的第一个参数中,存在一个特殊的属性raw
,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。
function tag(strings) {
return strings.raw[0];
}
tag`'string text line 1 \n string text line 2'`; // "'string text line 1 \n string text line 2'"
例子
[].map.call`${eval}\\u{61}lert\x281337\x29`
function x(){
alert(arguments[0]);
arguments[1]('hello')
}
function y(str){
alert(str);
}
x`x${y}x`