JavaScript - 标签模板

你好,未来的 JavaScript 巫师们!今天,我们将踏上一段令人兴奋的旅程,探索标签模板(Tagged Templates)的世界。如果你之前从未听说过它们,不用担心——在本课结束时,你将成为一个标签模板的高手!

JavaScript - Tagged Templates

什么是标签模板?

标签模板是 ES6(ECMAScript 2015)中引入的一个强大特性,它允许你使用一个函数来解析模板字符串。我知道这听起来可能有点吓人,但把它想象成给你的模板字符串赋予超能力!

用更简单的术语来说,标签模板让你在最终渲染之前处理模板字符串。这就好比有一个私人助手,在你发送消息之前能够修改它们。

基本语法

让我们从基本语法开始:

function myTag(strings, ...values) {
// 你的魔法在这里
}

const result = myTag`Hello, ${name}!`;

在这个例子中,myTag 是我们的模板标签函数。它接收两种类型的参数:

  1. 一个字符串字面量的数组
  2. 插入的值(那些在 ${} 里面的)

为什么使用标签模板?

你可能在想,“我为什么要麻烦使用标签模板?”让我给你讲一个小故事。

曾经有一个年轻的开发者名叫 Alex。Alex 在构建一个消息应用,并希望确保没有人能在他们的消息中发送有害的 HTML。标签模板来拯救了!Alex 使用它们来清理用户输入,防止潜在的安全风险。

标签模板对于以下用途非常实用:

  • 清理用户输入
  • 国际化(i18n)
  • 样式化(如在 React 的 styled-components 中)
  • 以及更多!

标签模板的示例

让我们通过一些示例来了解一下标签模板的实际应用!

示例 1:一个简单的问候

function greet(strings, ...values) {
return `${strings[0]}${values[0].toUpperCase()}${strings[1]}`;
}

const name = "alice";
console.log(greet`Hello, ${name}!`);
// 输出:Hello, ALICE!

在这个例子中,我们的 greet 函数接收名字并将其转换为大写。strings 数组包含 ["Hello, ", "!"],而 values 数组包含 ["alice"]

示例 2:HTML 转义

function safeHtml(strings, ...values) {
const escapeHtml = (str) => {
return str.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#039;");
};

return strings.reduce((result, string, i) => {
return result + string + (values[i] ? escapeHtml(values[i]) : '');
}, '');
}

const userInput = '<script>alert("XSS attack!")</script>';
console.log(safeHtml`User input: ${userInput}`);
// 输出:User input: &lt;script&gt;alert(&quot;XSS attack!&quot;)&lt;/script&gt;

这个示例展示了我们如何使用标签模板来转义可能有害的 HTML。我们的 safeHtml 函数将特殊字符替换为其 HTML 实体等价物。

示例 3:使用标签模板进行样式化

function css(strings, ...values) {
return strings.reduce((result, string, i) => {
return result + string + (values[i] || '');
}, '');
}

const color = 'red';
const fontSize = '20px';

const styles = css`
color: ${color};
font-size: ${fontSize};
`;

console.log(styles);
// 输出:
//   color: red;
//   font-size: 20px;

这个示例演示了如何使用标签模板进行样式化,类似于在 styled-components 这样的库中的使用方式。

高级用法:标签模板方法

标签模板还可以附带有方法。让我们看一个例子:

function currency(strings, ...values) {
const result = strings.reduce((acc, str, i) => {
return acc + str + (values[i] || '');
}, '');

return {
toString() {
return result;
},
USD() {
return '$' + result;
},
EUR() {
return '€' + result;
}
};
}

const amount = 100;
const formatted = currency`${amount}`;

console.log(formatted.toString()); // 输出:100
console.log(formatted.USD()); // 输出:$100
console.log(formatted.EUR()); // 输出:€100

在这个例子中,我们的 currency 标签返回一个带有方法的对象,允许进行灵活的格式化选项。

结论

标签模板是 JavaScript 中一个强大的特性,允许进行复杂的字符串操作和处理。它们不仅仅是连接字符串的时髦方式——它们为创建更安全、更灵活、更表达性的代码开辟了无限可能。

记住,像任何强大的工具一样,标签模板应该谨慎使用。它们对于清理、国际化或创建特定领域的语言等特定用例非常棒,但对于简单的字符串插值,常规的模板字面量通常就足够了。

既然你已经了解了标签模板,为什么不尝试创建你自己的呢?从小处开始,也许从一个简单的格式化函数开始,然后逐渐过渡到更复杂的使用场景。祝你好运,未来的 JavaScript 大师们!

方法 描述
strings.raw 提供访问模板字面量中的原始字符串的方法
String.raw 一个内置的标签函数,用于获取模板字面量的原始字符串形式

Credits: Image by storyset