已经同步到个人博客,欢迎访问
标签模板
完成highLight
函数,可以把模板字符串中的插入内容替换掉,并且插入文档后显示红色,例如:
const yourName = 'ScriptOJ'
const myName = 'Jerry'
document.body.innerHTML = highlight`Hello, ${yourName}. I am ${myName}.`
CSS样式:
.red {
color: red
}
上面的关键是函数调用那一行:
highlight`Hello, ${yourName}. I am ${myName}.`
以我浅薄的学识,认为是题目出错了,哪有这样进行函数调用的,所以自作主张按照下面的调用方式实现:
highlight('Hello, ${yourName}. I am ${myName}.')
按照这种形式,以前联系过类似的问题,使用new Function
可以实现替换模板字符串变量的功能:
const highlight = (str) => {
let reg = /\$\{(.+?)\}/g;
let match = reg.exec(str);
let result = [];
while(match) {
result.push(match[1]);
match = reg.exec(str);
}
return str.replace(reg, (match, p1) => {
const string = new Function(...result, `return ${p1}`)(...result.map(v => eval(v)));
return `${string}`
})
};
但是实际上,题目根本没有出错,就是这样的调用形式:
highlight`Hello, ${yourName}. I am ${myName}.`
这种调用形式叫做标签模板功能。
模板字符串可以紧跟在一个函数后面,函数将被用来处理这个模板字符串,这就是标签模板功能:
alert`123`
// 等同于
alert(123)
标签模板其实不是模板,而是函数调用的一种形式,函数后面紧跟的字符串就是函数的参数。
当字符串中有变量时,会将模板字符串处理为多个参数,再调用函数,比如:
const a = 5;
const b = 10;
alert`hello ${a + b} world ${a * b}`
// 等同于
alert(['hello ', ' world', ''], 5, 10)
alert
的返回值就是函数处理模板字符串后的返回值,函数会接收到多个参数:
function tag(stringArr, value1, value2){
// ...
}
// 等同于
function tag(stringArr, ...values){
// ...
}
函数的第一个参数是一个数组,数组的成员是模板字符串中没有变量替换的部分,也就是说,变量替换只发生在各个数组成员之间
函数的其他参数,都是模板字符各个变量被替换后的值
回到题目上来
highlight`Hello, ${yourName}. I am ${myName}`.
实际上函数调用是:
function highlight(['hello, ', '. I am ', ''], yourName, myName) {}
所以可以这样:
const highlight = (strArray, ...rest) => {
return strArray.map((v, key) => v + `${rest[key] || ''}`).join('')
};
另外,有一个String.raw
方法,它可以获取一个模板字符串的原始字面量值的
比如:
let name = "Bob";
String.raw `Hi\n${name}!`;
// "Hi\\nBob!",内插表达式还可以正常运行
以后用到的时候再看MDN的文档。