一文读懂JavaScript模板字面量:告别繁琐的字符串拼接

发布于:2024-04-29 ⋅ 阅读:(24) ⋅ 点赞:(0)

引言

JavaScript 中的模板字面量(Template Literals)是一种强大的字符串表示方式,允许开发者编写多行字符串、嵌入表达式,并进行便捷的字符串拼接。模板字面量可以分为不带标签的(Untagged Template Literals)和带标签的(Tagged Template Literals)。以下是这两种类型的使用教程、应用场景以及使用技巧的详细说明。

不带标签的模板字面量

使用教程

不带标签的模板字面量是最常见的形式,其特点是使用反引号()来包围字符串内容,而其中的插值表达式则由 ${}` 包裹。基本语法如下:

const name = "Alice";
const age = 25;

// 不带标签的模板字面量
const greeting = `Hello, ${name}! You are ${age} years old.`;
console.log(greeting); // 输出: Hello, Alice! You are 25 years old.

在这个例子中,${name}${age} 是插值表达式,它们会被各自的变量值替换。

应用场景

  • 多行字符串:无需使用换行符或字符串连接操作符,直接在模板字面量内部换行即可:
const poem = `Roses are red,
            Violets are blue,
            Sugar is sweet,
            And so are you.`;
  • 字符串插值:在字符串中动态插入变量值、表达式结果等:
const price = 19.99;
const taxedPrice = `The total cost with tax is $${price * 1.1}.`;
  • 复杂字符串格式化:结合函数调用、对象属性访问等进行更复杂的字符串构建:
const user = { firstName: "John", lastName: "Doe" };
const message = `Welcome, ${user.firstName} ${user.lastName}!`;

// 或者使用方法调用
const date = new Date();
const formattedDate = `Today's date is ${date.toLocaleDateString()} (${date.toLocaleTimeString()}).`;

使用技巧

  • 避免转义:由于模板字面量不需要转义特殊字符(如 \n\t),因此它们比传统字符串更易于阅读和编写。

  • 模板嵌套:可以在一个模板字面量内嵌套另一个模板字面量,实现层次化的字符串构建:

const outer = `Outer: ${`Inner: ${'Nested Content'}`}`;
console.log(outer); // 输出: Outer: Inner: Nested Content

带标签的模板字面量

使用教程

带标签的模板字面量是在不带标签的基础上,前面添加一个函数名(即标签函数),用于对整个模板及其插值进行自定义处理。基本语法如下:

function myTagFunction(strings, ...values) {
  // strings 是一个包含模板中所有文本片段的数组
  // values 是与插值对应的表达式求值结果的数组

  // 在这里对 strings 和 values 进行自定义处理,然后返回结果字符串
}

const name = "Bob";
const job = "Developer";

// 带标签的模板字面量
const bio = myTagFunction`My name is ${name}, and I am a ${job}.`;
console.log(bio);

应用场景

  • 自定义字符串格式化:例如,实现HTML转义、CSS字符串构建、本地化(i18n)、颜色编码、条件渲染等:
function htmlEscape(strings, ...values) {
  return strings.reduce((acc, str, i) => {
    acc += str;
    if (i < values.length) {
      acc += escape(values[i]); // 或其他HTML转义逻辑
    }
    return acc;
  }, "");
}

const escapedHtml = htmlEscape`<p>${userInput}</p>`;
  • 逻辑运算:在模板内部执行条件判断、循环等逻辑,简化字符串生成代码:
function conditional(strings, ...values) {
  return strings.reduce((acc, str, i) => {
    acc += str;
    if (i < values.length && values[i]) {
      acc += values[i];
    }
    return acc;
  }, "");
}

const result = conditional`You have ${items ? `${items.length} items` : 'no items'}.`;
  • 模板编译:在高级场景中,可以利用标签函数将模板转化为AST(抽象语法树)、编译为其他语言(如SQL查询、GraphQL查询等):
function compileToSQL(strings, ...values) {
  // 在这里将模板和值转化为SQL语句并返回
}

const query = compileToSQL`SELECT * FROM users WHERE id = ${userId}`;

使用技巧

  • 利用剩余操作符:在标签函数定义中使用剩余操作符 (...) 来收集所有插值表达式的值,方便处理。

  • 理解字符串数组与插值的关系strings 参数包含了模板中所有文本片段,其顺序与模板中的文本部分一致。values 数组对应于各个插值表达式的求值结果,两者按位置一一对应。

  • 封装常用逻辑:创建通用的标签函数库,封装如HTML转义、JSON.stringify等常见操作,提高代码复用性。

写在最后

总结来说,不带标签的模板字面量提供了一种简洁直观的方式来创建多行字符串和进行字符串插值,极大地提高了字符串处理的便利性。而带标签的模板字面量则允许开发者自定义模板处理逻辑,提供了无限的扩展可能,适用于需要高级字符串处理、模板编译或特定领域逻辑的场景。理解和熟练运用这两种模板字面量,能有效提升JavaScript编程的效率和代码质量。

喜欢的话帮忙点个赞 + 关注吧,将持续更新 JavaScript 相关的文章,还可以关注我的公众号 梁三石FE ,感谢您的关注~