我们简要介绍了 template literals,但它们有一个额外的功能,我们没有讨论:标签. 你可以用一个函数标记你的模板字母,并可以作为模板字母的内容的一种预处理器。
以下是典型的模板字面示例:
1let name = 'Benedict';
2let occupation = 'being awesome';
3
4let sentence = `Hi! I'm ${ name } and I'm busy at ${ occupation }.`;
5
6console.log(sentence);
7// Hi! I'm Benedict and I'm busy at being awesome.
现在让我们用一个无用的函数标记字母:
1function useless(strings, ...values) {
2 return 'I render everything useless.';
3}
4
5let name = 'Benedict';
6let occupation = 'being awesome';
7
8let sentence = useless`Hi! I'm ${ name } and I'm busy at ${ occupation }.`;
9
10console.log(sentence);
11// I render everything useless.
显然,上述没有任何用处,但它开始具有更多的功率是当我们使用字符串和值来构建模板时,需要一些处理。
以我们当前的例子:
- strings 是一个具有 3 个值的数组: Hi! I'm, and I'm busy at and.
- 值是一个具有
名称
和占用
变量的 2 个交互值的数组。这些值作为附加参数传递给标记函数,但在这里我们使用 rest parameters来将所有附加参数集合到一个 values 数组
使用我们的例子,如果当时句子末尾没有期限,一个空的字符串将是 strings 数组的最后一个值,以满足需要另一个字符串值的事实。
因此,凭借这些知识,我们可以创建一个标签函数,用于字母字符串,它实际上做了一些事情:
1function uppercase(strings, ...values) {
2 let newStr = '';
3
4 for (let i = 0; i < strings.length; i++) {
5 if (i > 0) {
6 newStr += values[i-1].toUpperCase();
7 }
8 newStr += strings[i];
9 }
10
11 return newStr;
12}
13
14let name = 'Benedict';
15let occupation = 'being awesome';
16
17let sentence = uppercase`Hi! I'm ${ name } and I'm busy at ${ occupation }.`;
18
19console.log(sentence);
20// Hi! I'm BENEDICT and I'm busy at BEING AWESOME.