字面量与模板字符串
2025年3月7日大约 7 分钟
字面量与模板字符串
字面量是在代码中直接表示值的表示法。本文将介绍JavaScript中的各种字面量,以及ES6引入的模板字符串功能。
什么是字面量
字面量(Literal)是在源代码中直接表示的固定值,不需要计算。JavaScript中的字面量允许你直接在代码中表示各种数据类型的值。
数字字面量
JavaScript支持多种形式的数字字面量:
整数字面量
// 十进制(最常用)
const decimal = 42;
// 十六进制(以0x或0X开头)
const hexadecimal = 0x2A; // 等于十进制的42
const anotherHex = 0XFF; // 等于十进制的255
// 八进制(在严格模式下以0o或0O开头,否则可以用0开头)
const octal = 0o52; // 等于十进制的42
const legacyOctal = 052; // 不推荐使用,在严格模式下会报错
// 二进制(以0b或0B开头)
const binary = 0b101010; // 等于十进制的42
浮点数字面量
// 小数点表示法
const float1 = 3.14;
const float2 = 0.5;
const float3 = .5; // 可以省略小数点前的0
// 科学计数法(e或E后跟正负指数)
const scientific1 = 3e8; // 3 * 10^8 = 300000000
const scientific2 = 1.23e-4; // 1.23 * 10^-4 = 0.000123
特殊数字字面量
// 无穷大
const positiveInfinity = Infinity;
const negativeInfinity = -Infinity;
// 非数字
const notANumber = NaN;
BigInt字面量
BigInt是ES2020引入的新数据类型,用于表示任意精度的整数:
// BigInt字面量(在数字后加n)
const bigInt = 9007199254740991n;
const anotherBigInt = 123n;
字符串字面量
字符串字面量是由单引号、双引号或反引号包围的字符序列:
单引号和双引号字符串
// 单引号字符串
const singleQuoted = '这是一个字符串';
// 双引号字符串
const doubleQuoted = "这也是一个字符串";
// 引号嵌套
const nested1 = "他说:'你好!'";
const nested2 = '她回答:"你好!"';
转义字符
字符串中可以使用反斜杠(\
)引入特殊字符:
// 常用转义字符
const newline = "第一行\n第二行";
const tab = "姓名\t年龄";
const quote = "他说:\"你好!\"";
const backslash = "这是一个反斜杠:\\";
// 其他转义字符
const carriageReturn = "回车符\r";
const formFeed = "换页符\f";
const backspace = "退格符\b";
const verticalTab = "垂直制表符\v";
Unicode转义序列
// Unicode转义序列
const heart = "\u2764"; // ❤
const smile = "\uD83D\uDE00"; // 😀(使用代理对表示超出BMP的字符)
// Unicode代码点转义(ES6)
const panda = "\u{1F43C}"; // 🐼
布尔字面量
布尔字面量只有两个值:
const isTrue = true;
const isFalse = false;
null和undefined字面量
// null表示空值或不存在的对象引用
const emptyValue = null;
// undefined表示未初始化的变量或不存在的属性
let undefinedValue;
console.log(undefinedValue); // undefined
对象字面量
对象字面量是由花括号包围的零个或多个属性名-值对的列表:
基本对象字面量
// 空对象
const emptyObject = {};
// 包含属性的对象
const person = {
name: "张三",
age: 30,
isEmployed: true
};
// 嵌套对象
const student = {
name: "李四",
scores: {
math: 95,
english: 88,
science: 92
}
};
ES6增强的对象字面量
ES6为对象字面量引入了几个新特性:
// 属性简写(当属性名与变量名相同时)
const name = "王五";
const age = 25;
const user = { name, age }; // 等同于 { name: name, age: age }
// 方法简写
const calculator = {
add(a, b) {
return a + b;
},
subtract(a, b) {
return a - b;
}
// 等同于 add: function(a, b) { ... }
};
// 计算属性名
const propName = "dynamicProperty";
const obj = {
[propName]: "这是一个动态属性名",
["computed" + "Name"]: "计算属性名"
};
数组字面量
数组字面量是由方括号包围的零个或多个表达式的列表:
// 空数组
const emptyArray = [];
// 包含元素的数组
const numbers = [1, 2, 3, 4, 5];
const mixed = [1, "two", true, null, { key: "value" }];
// 稀疏数组(包含空槽)
const sparse = [1, , 3]; // 第二个元素是空槽
console.log(sparse.length); // 3
console.log(sparse[1]); // undefined
// 嵌套数组
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
正则表达式字面量
正则表达式字面量是由斜杠包围的模式和可选的标志:
// 基本正则表达式
const pattern1 = /abc/;
const pattern2 = /\d+/; // 匹配一个或多个数字
// 带标志的正则表达式
const globalPattern = /abc/g; // 全局匹配
const caseInsensitive = /abc/i; // 忽略大小写
const multiline = /^abc/m; // 多行模式
const unicode = /\u{1F4A9}/u; // Unicode模式
const sticky = /abc/y; // 粘性匹配
const dotAll = /./s; // 点号匹配所有字符(包括换行符)
// 使用正则表达式
const text = "abc123def";
console.log(pattern2.test(text)); // true
console.log(text.match(pattern2)); // ["123"]
函数字面量(函数表达式)
函数字面量定义了一个函数值:
// 命名函数表达式
const namedFunction = function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
};
// 匿名函数表达式
const anonymousFunction = function(a, b) {
return a + b;
};
// 箭头函数(ES6)
const arrowFunction = (a, b) => a + b;
const multilineArrow = (a, b) => {
const result = a + b;
return result;
};
模板字符串
模板字符串是ES6引入的一种新型字符串字面量,使用反引号(`)包围:
基本语法
// 基本模板字符串
const greeting = `你好,世界!`;
// 多行字符串
const multiline = `这是第一行
这是第二行
这是第三行`;
// 在旧版JavaScript中实现多行字符串
const oldMultiline = "这是第一行\n" +
"这是第二行\n" +
"这是第三行";
字符串插值
模板字符串最强大的特性是支持插值表达式:
// 变量插值
const name = "张三";
const greeting = `你好,${name}!`;
console.log(greeting); // "你好,张三!"
// 表达式插值
const a = 5;
const b = 10;
console.log(`${a} + ${b} = ${a + b}`); // "5 + 10 = 15"
// 调用函数
function capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
console.log(`${capitalize("javascript")} 是一种编程语言`); // "Javascript 是一种编程语言"
// 条件表达式
const isLoggedIn = true;
console.log(`用户${isLoggedIn ? "已登录" : "未登录"}`); // "用户已登录"
// 嵌套模板
const nestedTemplate = `外层 ${`内层 ${name}`}`;
标签模板字符串
标签模板是一种更高级的模板字符串用法,允许你自定义模板字符串的处理方式:
// 定义标签函数
function highlight(strings, ...values) {
let result = "";
strings.forEach((string, i) => {
result += string;
if (i < values.length) {
result += `<span class="highlight">${values[i]}</span>`;
}
});
return result;
}
// 使用标签模板
const name = "李四";
const age = 30;
const html = highlight`我的名字是${name},今年${age}岁。`;
console.log(html);
// "我的名字是<span class="highlight">李四</span>,今年<span class="highlight">30</span>岁。"
原始字符串
通过标签函数的String.raw
属性,可以获取模板字符串的原始内容,不处理转义序列:
// 普通模板字符串会处理转义序列
console.log(`换行符:\n`); // 输出一个实际的换行
// 原始字符串不处理转义序列
console.log(String.raw`换行符:\n`); // 输出 "换行符:\n"
// 自定义标签函数访问原始字符串
function showRaw(strings, ...values) {
console.log(strings.raw); // 原始字符串数组
}
showRaw`换行符:\n`;
实际应用示例
构建动态HTML
function createUserCard(user) {
return `
<div class="user-card">
<img src="${user.avatar}" alt="${user.name}的头像">
<h2>${user.name}</h2>
<p>${user.isVIP ? '⭐ VIP用户' : '普通用户'}</p>
<p>注册时间:${new Date(user.registerDate).toLocaleDateString()}</p>
</div>
`;
}
const user = {
name: "王五",
avatar: "https://example.com/avatar.jpg",
isVIP: true,
registerDate: "2023-01-15"
};
document.body.innerHTML = createUserCard(user);
构建SQL查询
function buildQuery(table, filters) {
const conditions = Object.entries(filters)
.map(([key, value]) => `${key} = '${value}'`)
.join(' AND ');
return `SELECT * FROM ${table} WHERE ${conditions}`;
}
const query = buildQuery('users', { status: 'active', age: '30' });
console.log(query); // "SELECT * FROM users WHERE status = 'active' AND age = '30'"
国际化字符串
function i18n(strings, ...values) {
// 假设这是一个翻译函数
const translate = str => {
const translations = {
'Hello': '你好',
'Welcome': '欢迎',
'to': '来到'
};
return translations[str] || str;
};
return strings.reduce((result, string, i) => {
let value = i < values.length ? values[i] : '';
return result + translate(string) + value;
}, '');
}
const name = 'JavaScript';
const greeting = i18n`Hello, ${name}! Welcome to our website.`;
总结
JavaScript的字面量和模板字符串提供了直观、灵活的方式来表示各种数据类型的值:
- 数字字面量支持十进制、十六进制、八进制、二进制和科学计数法
- 字符串字面量可以使用单引号、双引号或反引号(模板字符串)
- 对象字面量和数组字面量提供了创建复杂数据结构的简洁语法
- 模板字符串支持多行文本、字符串插值和标签模板,极大地增强了字符串处理能力
模板字符串特别适合处理包含动态内容的复杂字符串,如HTML片段、SQL查询和国际化文本,使代码更加清晰和易于维护。
练习
- 使用对象字面量和ES6的增强特性,创建一个表示图书的对象
- 编写一个函数,使用模板字符串生成一个HTML表格,显示数组中的数据
- 创建一个自定义的标签模板函数,用于转义HTML特殊字符