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攻击!")</script>';
console.log(safeHtml`用户输入: ${userInput}`);
// 输出:用户输入: &lt;script&gt;alert(&quot;XSS攻击!&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