第11章:JavaScript标准库(Standard Library)
一、导读
1.1 本章学习目标
第11章介绍JavaScript的标准库。本章核心目标:
- 掌握集合类型:Set、Map、WeakSet、WeakMap
- 熟练使用正则表达式:创建、测试、匹配
- 掌握日期处理:Date对象
- 了解国际化API:Intl对象
- 掌握JSON处理
1.2 为什么本章如此重要
JavaScript标准库提供了强大的内置功能。Set和Map提供了高效的数据结构,正则表达式是文本处理的利器,Date和Intl处理日期和国际化。掌握这些内置功能能大大提高开发效率。
1.3 核心问题引导
Set和Array有什么区别?什么时候用Set?
Map和普通对象有什么区别?
正则表达式的贪婪匹配和非贪婪匹配有什么区别?
WeakMap的"弱引用"是什么意思?
二、核心概念详解
11.1 Set和Map
javascript
// Set:不重复的值集合
let set = new Set([1, 2, 3, 2, 1]);
console.log(set.size); // 3
set.add(4);
set.delete(1);
console.log(set.has(2)); // true
// 遍历
for (let item of set) {
console.log(item);
}
// 数组去重
let arr = [1, 2, 2, 3, 3, 3];
let unique = [...new Set(arr)];
console.log(unique); // [1, 2, 3]
// Map:键值对集合
let map = new Map();
map.set("name", "Alice");
map.set("age", 20);
console.log(map.get("name")); // "Alice"
console.log(map.size); // 2
// 遍历
for (let [key, value] of map) {
console.log(`${key}: ${value}`);
}
// Map vs Object
// Map的键可以是任意类型
let objKey = {};
map.set(objKey, "value");
console.log(map.get(objKey)); // "value"
// WeakMap:弱引用
let wm = new WeakMap();
let obj = {};
wm.set(obj, "value");
// obj被垃圾回收后,wm中的条目也会被移除
// WeakMap不可遍历11.2 正则表达式
javascript
// 创建正则
let regex1 = /hello/i; // 字面量
let regex2 = new RegExp("hello", "i"); // 构造函数
// 测试
let str = "Hello, World!";
console.log(regex1.test(str)); // true
console.log(str.match(regex1)); // ["Hello"]
// 常用模式
let email = "test@example.com";
let emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(emailRegex.test(email)); // true
// 替换
let text = "Hello 123 World 456";
let result = text.replace(/\d+/g, "NUM");
console.log(result); // "Hello NUM World NUM"
// 分组和捕获
let dateStr = "2024-01-15";
let dateRegex = /(\d{4})-(\d{2})-(\d{2})/;
let match = dateStr.match(dateRegex);
console.log(match[1]); // "2024"
console.log(match[2]); // "01"
console.log(match[3]); // "15"
// 命名捕获组
let namedRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
let namedMatch = dateStr.match(namedRegex);
console.log(namedMatch.groups.year); // "2024"
console.log(namedMatch.groups.month); // "01"
// 常用方法
console.log("hello".search(/l/)); // 2
console.log("hello".split(/\s+/)); // ["hello"]11.3 Date对象
javascript
// 创建日期
let now = new Date();
let specific = new Date("2024-01-15");
let fromParts = new Date(2024, 0, 15); // 月份从0开始
// 获取组件
console.log(now.getFullYear());
console.log(now.getMonth() + 1); // 0-11
console.log(now.getDate());
console.log(now.getDay()); // 星期几(0-6)
console.log(now.getHours());
console.log(now.getMinutes());
console.log(now.getTime()); // 时间戳
// 格式化
console.log(now.toISOString());
console.log(now.toLocaleDateString("zh-CN"));
console.log(now.toLocaleTimeString("zh-CN"));
// Intl.DateTimeFormat
let formatter = new Intl.DateTimeFormat("zh-CN", {
year: "numeric",
month: "long",
day: "numeric",
weekday: "long"
});
console.log(formatter.format(now));
// 日期计算
let tomorrow = new Date(now);
tomorrow.setDate(tomorrow.getDate() + 1);
// 时间差
let start = new Date("2024-01-01");
let end = new Date("2024-12-31");
let diff = end - start;
let days = Math.floor(diff / (1000 * 60 * 60 * 24));
console.log(days);11.4 JSON
javascript
// 序列化
let obj = {name: "Bob", age: 25, hobbies: ["reading", "coding"]};
let jsonStr = JSON.stringify(obj);
console.log(jsonStr);
// 格式化输出
console.log(JSON.stringify(obj, null, 2));
// 自定义序列化
let custom = JSON.stringify(obj, (key, value) => {
if (key === "age") return undefined; // 过滤掉age
return value;
});
// 解析
let parsed = JSON.parse(jsonStr);
console.log(parsed.name);
// 处理日期
let withDate = {name: "Alice", date: new Date()};
let serialized = JSON.stringify(withDate);
let deserialized = JSON.parse(serialized, (key, value) => {
if (key === "date") return new Date(value);
return value;
});三、实战案例
3.1 文本分析工具
javascript
class TextAnalyzer {
constructor(text) {
this.text = text;
}
wordCount() {
return this.text.split(/\s+/).filter(w => w.length > 0).length;
}
charCount() {
return this.text.length;
}
mostCommonWords(n = 5) {
const words = this.text.toLowerCase()
.match(/\b\w+\b/g) || [];
const freq = new Map();
for (const word of words) {
freq.set(word, (freq.get(word) || 0) + 1);
}
return [...freq.entries()]
.sort((a, b) => b[1] - a[1])
.slice(0, n);
}
extractEmails() {
const regex = /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g;
return this.text.match(regex) || [];
}
extractUrls() {
const regex = /https?:\/\/[^\s]+/g;
return this.text.match(regex) || [];
}
}
const text = `
Contact us at support@example.com or visit https://example.com.
We also have info@example.com for more details.
`;
const analyzer = new TextAnalyzer(text);
console.log("Words:", analyzer.wordCount());
console.log("Top words:", analyzer.mostCommonWords(3));
console.log("Emails:", analyzer.extractEmails());
console.log("URLs:", analyzer.extractUrls());四、本章小结
第11章介绍了JavaScript标准库:Set/Map集合、正则表达式、Date日期处理、JSON序列化、Intl国际化。这些内置功能提供了强大的数据处理能力。
五、思考与练习
思考题
Set的时间复杂度是多少?和Array相比有什么优势?
正则表达式的回溯是什么?如何避免性能问题?
Date对象有什么已知问题?Temporal API如何解决?
JSON不能序列化哪些JavaScript值?
编程练习
使用Set实现集合运算(并集、交集、差集)。
编写一个正则表达式验证密码强度。
实现一个日期范围选择器。