标签模板函数(Tagged Template)是 JavaScript 中模板字符串的高级用法,允许通过自定义函数处理模板字符串的各个部分。该函数接收模板的静态字符串和动态表达式值,可进行灵活操作(如转义、翻译、格式化等)。以下是详细说明及示例:
标签函数以模板字符串为参数,形式为:
function tagFunction(strings, ...values) {
// strings: 模板中的静态字符串数组
// values: 模板中的动态表达式值数组
return processedResult;
}
// 使用方式
const result = tagFunction`模板内容`;
参数 | 含义 |
---|---|
strings |
字符串数组,保存模板中所有静态部分(例如 Hello ${name} 中的 'Hello ' 和 '' ) |
values |
动态表达式的计算结果数组(例如 ${name} 的值) |
function upperTag(strings, ...values) {
let result = "";
for (let i = 0; i < strings.length; i++) {
result += strings[i];
if (i < values.length) {
result += String(values[i]).toUpperCase();
}
}
return result;
}
const name = "alice";
const age = 25;
console.log(upperTag`Name: ${name}, Age: ${age}`);
// 输出: Name: ALICE, Age: 25
function safeHTML(strings, ...values) {
let escaped = "";
for (let i = 0; i < strings.length; i++) {
escaped += strings[i];
if (i < values.length) {
escaped += String(values[i])
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
}
return escaped;
}
const userInput = '';
const html = safeHTML`${userInput}`;
console.log(html);
// 输出: <script>alert("xss")</script>
const translations = {
en: { greeting: "Hello", farewell: "Goodbye" },
es: { greeting: "Hola", farewell: "Adiós" }
};
function i18n(lang) {
return function(strings, ...keys) {
let result = "";
strings.forEach((str, i) => {
result += str;
if (i < keys.length) {
result += translations[lang][keys[i]] || keys[i];
}
});
return result;
};
}
const translate = i18n("es");
console.log(translate`${"greeting"} World! ${"farewell"}`);
// 输出: Hola World! Adiós
function css(strings, ...values) {
const styles = [];
strings.forEach((str, i) => {
styles.push(str);
if (i < values.length) styles.push(values[i]);
});
return styles.join("");
}
const color = "red";
const fontSize = 16;
const style = css`
.button {
color: ${color};
font-size: ${fontSize}px;
padding: 10px;
}
`;
console.log(style);
// 输出: .button { color: red; font-size: 16px; padding: 10px; }
function conditionalTag(strings, ...values) {
let output = "";
strings.forEach((str, i) => {
const value = values[i];
// 跳过 false、null、undefined、空字符串
if (value != null && value !== false && value !== "") {
output += str + value;
} else {
output += str;
}
});
return output;
}
const isAdmin = false;
const username = "Alice";
const message = conditionalTag`
Welcome${isAdmin ? " Admin" : ""}, ${username}!
${isAdmin ? "Access Level: 10" : ""}
`;
console.log(message);
// 输出: Welcome, Alice! (自动跳过无效条件部分)
标签函数可以返回任意类型的值,不限于字符串:
function createDOM(strings, ...values) {
const html = strings.reduce((acc, str, i) =>
acc + str + (values[i] || ""), "");
const template = document.createElement("template");
template.innerHTML = html.trim();
return template.content;
}
const dom = createDOM`
${"Title"}
${"Content..."}
`;
document.body.appendChild(dom);
特性 | 说明 |
---|---|
核心能力 | 自定义处理模板字符串的静态部分和动态表达式 |
参数结构 | (strings: string[], ...values: any[]) |
应用场景 | 安全转义、国际化、样式生成、条件渲染、自定义模板引擎等 |
返回值 | 可以是字符串、DOM 节点、对象等任意类型 |
优势 | 提升模板处理的灵活性和安全性,减少重复代码 |
通过标签模板函数,开发者可以扩展模板字符串的功能,使其适用于更复杂的场景,同时保持代码的可读性和维护性。