深入标签模板字面量

时间:2022-11-03 07:08:50

模板字面量是ES6引入的一个新特性,它的出现扩展了字符串的可用性,使得拼接字符串和变量变得更加方便和全面。但它不仅限于拼接字符串和变量。还可以用于进行特殊函数调用,ES6将这一功能定义为标签模板字面量。

我们看一下代码:

function tag(parts, ...values) {
    return parts.reduce(
        (pre, cur, index) => pre + values[index - 1] + cur);
}

let name = 'World';
let language = 'JavaScript'
let text = tag`Hello, ${name}. This is ${language}!`
console.log(text);

运行以上代码,会出现什么结果呢,你或许想到了,控制台会打印'Hello, World. This is JavaScript!'。但你可能会感到疑惑,以上代码的运行机制是怎样的呢。下面我们就来深入了解一下标签模板字面量的运行机制。

首先,我们可以把标签模板字面量分为两部分:标签模板字面量。如你所见,上述代码中的tag就是一个标签,即你要调用的函数。而紧跟的模板字面量就是被tag函数将要解析的传入参数。实际上,tag会将模板字面量如下解析:

tag(['Hello, ', '. This is ', '!'], 'Maurice', 'thrilled') {
...
}

终于明白了!原来标签模板字面量是这样的运行机制。首先解析所有模板字面量中的非插值内容,构成一个列表参数;然后将所有插值内容解析出来,处理为独立的参数。

标签模板还有一个更有用的用法,即可以用它来自动确保模板中插入表达式的安全性。假设有一个模板,其中所有表达式都是用户输入的内容,我们可以定义一个filter函数来移除 HTML 标签和类似的危害,从而阻止用户在网站中注入恶意的 HTML,防止跨域脚本(XSS)攻击:

function sanitized(parts, ...values) {
    return parts.reduce((all, part, index) =>
        all + sanitize(values[index - 1]) + part);
}
let comment = 'Evil comment<iframe src="http://evil.corp"></iframe>';
let html = sanitized`<div>${comment}</div>`;
console.log(html);
//'<div>Evil comment</div>'