> 技术文档 > 关于Web APIs总结第三篇(完)

关于Web APIs总结第三篇(完)


五.Bom操作

1.Window对象

1.1BOM(浏览器对象模型)

#mermaid-svg-0rFR2n6BJKWN5bvQ {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .error-icon{fill:#552222;}#mermaid-svg-0rFR2n6BJKWN5bvQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0rFR2n6BJKWN5bvQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .marker.cross{stroke:#333333;}#mermaid-svg-0rFR2n6BJKWN5bvQ svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0rFR2n6BJKWN5bvQ .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .cluster-label text{fill:#333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .cluster-label span{color:#333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .label text,#mermaid-svg-0rFR2n6BJKWN5bvQ span{fill:#333;color:#333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .node rect,#mermaid-svg-0rFR2n6BJKWN5bvQ .node circle,#mermaid-svg-0rFR2n6BJKWN5bvQ .node ellipse,#mermaid-svg-0rFR2n6BJKWN5bvQ .node polygon,#mermaid-svg-0rFR2n6BJKWN5bvQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0rFR2n6BJKWN5bvQ .node .label{text-align:center;}#mermaid-svg-0rFR2n6BJKWN5bvQ .node.clickable{cursor:pointer;}#mermaid-svg-0rFR2n6BJKWN5bvQ .arrowheadPath{fill:#333333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0rFR2n6BJKWN5bvQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-0rFR2n6BJKWN5bvQ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-0rFR2n6BJKWN5bvQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0rFR2n6BJKWN5bvQ .cluster text{fill:#333;}#mermaid-svg-0rFR2n6BJKWN5bvQ .cluster span{color:#333;}#mermaid-svg-0rFR2n6BJKWN5bvQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0rFR2n6BJKWN5bvQ :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} window navigater loaction document history screen

window对象是一个全局对象,也可以说是JavaScript中的顶级对象

像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的。

所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法

window对象下的属性和方法调用的时候可以省略window

1.2定时器-延时函数

JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout

语法:

setTimeout(回调函数,等待的毫秒数)

setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window

清除延时函数:

let timer = setTimeout(回调函数,等待的毫秒数)

clearTimeout(timer)

注意点

  1. 延时器需要等待,所以后面的代码先执行
  2. 每一次调用延时器都会产生一个新的延时器
1.3JS执行机制

JavaScript 的执行机制是其核心特性之一,涉及单线程事件循环(Event Loop)调用栈任务队列等概念。以下是详细解析:

1.3.1 单线程与异步

JavaScript 是单线程语言,但通过异步非阻塞机制处理并发操作(如网络请求、定时器等)。
关键点

  • 单线程:同一时间只能执行一个任务,避免多线程的复杂性(如死锁)。
  • 异步任务:通过回调函数、Promise、async/await 实现非阻塞操作。
1.3.2执行上下文(Execution Context)

代码执行时的环境,分为:

  • 全局执行上下文:代码首次执行时创建。
  • 函数执行上下文:每次调用函数时创建。
  • Eval 执行上下文(较少用)。

每个上下文包含:

  • 变量对象(VO):存储变量、函数声明。
  • 作用域链(Scope Chain):用于变量查找。
  • this 绑定:指向当前执行环境。
1.3.3. 调用栈(Call Stack)
  • **后进先出(LIFO)**结构,记录函数的调用顺序。
  • 函数执行时入栈,执行完毕出栈。
  • 栈溢出:递归过深时抛出 RangeError

示例

function foo() { console.log(\"foo\"); bar();}function bar() { console.log(\"bar\");}foo(); // 调用栈顺序: foo → bar
1.3.4. 事件循环(Event Loop)

协调调用栈和任务队列的机制,分为以下步骤:

(1) 任务分类

  • 同步任务:立即执行,进入调用栈。

  • 异步任务

    :分为两类:

    • 宏任务(Macro Task)setTimeoutsetInterval、DOM 事件、I/O 操作。
    • 微任务(Micro Task)Promise.thenMutationObserverqueueMicrotask

(2) 执行流程

  1. 执行全局同步代码(调用栈)。
  2. 遇到异步任务:
    • 宏任务 → 交给 Web API 处理,完成后回调放入宏任务队列
    • 微任务 → 回调放入微任务队列
  3. 调用栈为空时:
    • 优先清空微任务队列(全部执行)。
    • 取出宏任务队列的第一个任务执行。
  4. 重复步骤 3(事件循环)。

示例

console.log(\"1\"); // 同步setTimeout(() => console.log(\"2\"), 0); // 宏任务Promise.resolve().then(() => console.log(\"3\")); // 微任务console.log(\"4\"); // 同步// 输出顺序: 1 → 4 → 3 → 2
1.3.5任务队列(Task Queues)
  • 宏任务队列:每次事件循环处理一个宏任务。
  • 微任务队列:必须在当前宏任务结束后立即清空(优先级更高)。

执行顺序
同步代码 → 微任务 → 宏任务 → (下一轮循环)

1.3.6. 关键概念对比
特性 宏任务 微任务 示例 setTimeoutsetInterval Promise.thenqueueMicrotask 队列优先级 低 高(当前循环末尾执行) 触发时机 下一次事件循环 当前任务结束后立即执行
1.3.7. 常见面试题分析

题目 1

setTimeout(() => console.log(\"A\"), 0);Promise.resolve().then(() => console.log(\"B\"));console.log(\"C\");

答案C → B → A
解析:同步代码 C 最先执行;微任务 B 优先于宏任务 A

题目 2

console.log(\"Start\");setTimeout(() => console.log(\"Timeout\"), 0);Promise.resolve().then(() => { console.log(\"Promise\"); setTimeout(() => console.log(\"Inner Timeout\"), 0);});console.log(\"End\");

答案Start → End → Promise → Timeout → Inner Timeout
解析

  1. 同步代码 StartEnd
  2. 微任务 Promise 执行,其内部的 setTimeout 作为新宏任务加入队列。
  3. 执行初始宏任务 Timeout,最后执行 Inner Timeout
1.3.8. 总结
  • 调用栈处理同步任务,任务队列管理异步任务。
  • 微任务优先级高于宏任务
  • 事件循环是 JS 实现非阻塞的核心机制。

理解这些机制能有效避免异步编程中的常见问题(如执行顺序错误)。

1.4location对象

location 对象是浏览器提供的 JavaScript 内置对象,它包含了当前文档的 URL 信息,并提供了操作浏览器地址的方法。

1.4.1. location 对象属性

location 对象包含以下属性,这些属性都是可读写的(修改它们会导致浏览器导航到新的 URL):

属性 描述 示例 href 完整的 URL \"https://example.com:8080/path/?query=string#hash\" protocol 协议部分(包括冒号) \"https:\" host 主机名和端口号 \"example.com:8080\" hostname 主机名 \"example.com\" port 端口号 \"8080\" pathname URL 路径部分 \"/path/\" search 查询字符串(包括问号) \"?query=string\" hash 锚部分(包括井号) \"#hash\" origin 只读属性,返回协议+主机名+端口 \"https://example.com:8080\"
1.4.2. location 对象方法
方法 描述 示例 assign(url) 加载新文档 location.assign(\"https://new.com\") replace(url) 替换当前文档(不保留历史记录) location.replace(\"https://new.com\") reload() 重新加载当前页面 location.reload() reload(forceGet) 强制从服务器重新加载 location.reload(true) toString() 返回完整的 URL 字符串 location.toString()
1.4.3. 使用示例

获取当前 URL 信息

console.log(\"完整URL:\", location.href);console.log(\"协议:\", location.protocol);console.log(\"主机:\", location.host);console.log(\"路径:\", location.pathname);console.log(\"查询参数:\", location.search);console.log(\"锚点:\", location.hash);

修改 URL

// 导航到新页面(会添加到历史记录)location.href = \"https://new.com\";// 替换当前页面(不会添加到历史记录)location.replace(\"https://new.com\");// 修改查询字符串location.search = \"?page=2\";// 修改锚点(不会重新加载页面)location.hash = \"#section2\";

解析查询参数

function getQueryParams() { const params = {}; const queryString = location.search.substring(1); const pairs = queryString.split(\"&\"); pairs.forEach(pair => { const [key, value] = pair.split(\"=\"); params[decodeURIComponent(key)] = decodeURIComponent(value || \"\"); }); return params;}console.log(getQueryParams());

页面重定向

// 3秒后重定向setTimeout(() => { location.href = \"https://new.com\";}, 3000);// 条件重定向if (!userLoggedIn) { location.replace(\"/login\");}
1.4.4. 注意事项
  1. 修改 location 属性(除 hash 外)会导致页面重新加载
  2. replace() 方法不会在浏览器历史记录中创建新条目
  3. reload(true) 会绕过缓存,从服务器强制重新加载
  4. 现代前端框架(如 React、Vue)通常使用客户端路由,直接操作 location 可能会干扰框架的路由系统
1.4.5. 与 window.location 的关系

location 对象是 window 对象的属性,因此以下两种写法是等价的:

window.location.href;location.href;

在大多数情况下,可以省略 window. 前缀直接使用 location

1.5navigator对象

navigator 对象是浏览器提供的 JavaScript 内置对象,它包含了有关浏览器的信息,包括浏览器名称、版本、平台、用户代理字符串等。

1.5.1. navigator 对象常用属性
属性 描述 示例值 appName 浏览器名称 \"Netscape\" (大多数现代浏览器返回此值) appVersion 浏览器版本信息 \"5.0 (Windows NT 10.0; Win64; x64)\" userAgent 用户代理字符串 \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36\" platform 操作系统平台 \"Win32\" language 浏览器主语言 \"zh-CN\" languages 浏览器支持的语言数组 [\"zh-CN\", \"zh\", \"en-US\", \"en\"] cookieEnabled 是否启用cookie true onLine 是否联网 true hardwareConcurrency CPU核心数 8 deviceMemory 设备内存(GB) 8 maxTouchPoints 最大触摸点数 5
1.5.2. navigator 对象常用方法
方法 描述 示例 javaEnabled() 是否启用Java navigator.javaEnabled() sendBeacon() 异步发送少量数据 navigator.sendBeacon(url, data) vibrate() 触发设备震动(移动设备) navigator.vibrate(200) getBattery() 获取电池状态(Promise) navigator.getBattery().then(...) getUserMedia() 获取媒体设备访问权限 navigator.mediaDevices.getUserMedia(...) share() Web分享API navigator.share({title: \'分享标题\', url: \'https://example.com\'})
1.5.3. 使用示例

检测浏览器基本信息

console.log(\'浏览器名称:\', navigator.appName);console.log(\'浏览器版本:\', navigator.appVersion);console.log(\'用户代理:\', navigator.userAgent);console.log(\'操作系统:\', navigator.platform);console.log(\'是否在线:\', navigator.onLine);console.log(\'是否启用cookie:\', navigator.cookieEnabled);

检测浏览器类型

function detectBrowser() { const ua = navigator.userAgent; if (ua.indexOf(\'Chrome\') > -1) return \'Chrome\'; if (ua.indexOf(\'Firefox\') > -1) return \'Firefox\'; if (ua.indexOf(\'Safari\') > -1) return \'Safari\'; if (ua.indexOf(\'Opera\') > -1) return \'Opera\'; if (ua.indexOf(\'Edge\') > -1) return \'Edge\'; if (ua.indexOf(\'MSIE\') > -1 || ua.indexOf(\'Trident/\') > -1) return \'IE\'; return \'Unknown\';}console.log(\'当前浏览器:\', detectBrowser());

使用sendBeacon发送数据

// 在页面卸载时可靠地发送数据window.addEventListener(\'unload\', function() { const data = JSON.stringify({event: \'page_exit\', time: Date.now()}); navigator.sendBeacon(\'/analytics\', data);});

检测设备特性

console.log(\'CPU核心数:\', navigator.hardwareConcurrency);console.log(\'设备内存(GB):\', navigator.deviceMemory);// 检测是否移动设备const isMobile = /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent);console.log(\'是否移动设备:\', isMobile);

使用Web Share API

if (navigator.share) { document.getElementById(\'share-btn\').addEventListener(\'click\', async () => { try { await navigator.share({ title: \'Web分享示例\', text: \'看看这个有趣的网站\', url: \'https://example.com\' }); console.log(\'分享成功\'); } catch (err) { console.log(\'分享取消:\', err); } });} else { console.log(\'Web Share API不支持\');}
1.5.4. 注意事项
  1. 用户代理字符串不可靠userAgent可以被修改,不应仅依赖它来做关键功能检测
  2. 隐私考虑:某些属性如deviceMemory可能涉及隐私,浏览器可能限制访问
  3. 兼容性问题:新API如share()getBattery()等不是所有浏览器都支持
  4. 特性检测:推荐使用特性检测而非浏览器嗅探
1.5.5. 现代API扩展

现代navigator对象还包含许多新API:

  • 媒体设备navigator.mediaDevices (摄像头/麦克风访问)
  • 地理位置navigator.geolocation
  • 剪贴板navigator.clipboard
  • 蓝牙navigator.bluetooth
  • USBnavigator.usb
  • 网络信息navigator.connection

这些API通常需要用户授权才能使用。

1.6histroy对象

history 对象是浏览器提供的 JavaScript 内置对象,它允许开发者操作浏览器的会话历史记录(即当前标签页访问过的 URL 历史)。

1.6.1. history 对象属性
属性 描述 示例 length 返回历史记录列表中的 URL 数量(只读) history.length scrollRestoration 控制页面刷新后是否恢复滚动位置(auto/manualhistory.scrollRestoration = \'manual\' state 返回当前历史记录条目的状态对象(只读) history.state
1.6.2. history 对象方法
  1. 核心导航方法
方法 描述 示例 back() 后退到上一个页面(等同于浏览器后退按钮) history.back() forward() 前进到下一个页面(等同于浏览器前进按钮) history.forward() go(n) 在历史记录中前进或后退 n 个页面 history.go(-2) (后退2页)
  1. 现代 HTML5 History API
方法 描述 示例 pushState(state, title, url) 添加新的历史记录条目(不刷新页面) history.pushState({page: 1}, \"Page 1\", \"?page=1\") replaceState(state, title, url) 替换当前历史记录条目(不刷新页面) history.replaceState({page: 2}, \"Page 2\", \"?page=2\")
1.6.3. 使用示例
  1. 基本导航控制
// 后退一页document.getElementById(\'back-btn\').addEventListener(\'click\', () => { history.back();});// 前进一页document.getElementById(\'forward-btn\').addEventListener(\'click\', () => { history.forward();});// 前进或后退多页document.getElementById(\'go-btn\').addEventListener(\'click\', () => { history.go(-2); // 后退2页});
  1. 使用 History API 实现 SPA 路由
// 添加新历史记录function navigateTo(page) { const state = { page }; const title = `Page ${page}`; const url = `?page=${page}`; history.pushState(state, title, url); updateContent(page);}// 替换当前历史记录function replaceCurrentPage(page) { const state = { page }; const title = `Page ${page}`; const url = `?page=${page}`; history.replaceState(state, title, url); updateContent(page);}// 处理浏览器前进/后退window.addEventListener(\'popstate\', (event) => { const page = event.state?.page || 1; updateContent(page);});function updateContent(page) { document.getElementById(\'content\').textContent = `当前页面: ${page}`;}
  1. 状态管理示例
// 保存状态到历史记录history.pushState({ formData: { username: \'user123\', progress: 75 }}, \"Form Page\", \"/form\");// 恢复状态window.addEventListener(\'popstate\', (event) => { const savedState = event.state; if (savedState && savedState.formData) { console.log(\'恢复的表单数据:\', savedState.formData); // 填充表单... }});
  1. 禁止滚动恢复
// 禁用页面刷新后的自动滚动恢复if (history.scrollRestoration) { history.scrollRestoration = \'manual\';}
1.6.4. 注意事项
  1. 安全限制
    • 只能操作同源的历史记录
    • 不能直接查看历史记录中的具体URL(隐私保护)
  2. URL 参数
    • pushStatereplaceState 的 URL 参数必须同源
    • 修改 URL 不会触发页面加载,但会改变地址栏显示
  3. SEO 考虑
    • 使用 History API 的单页应用需要配置服务器端渲染
  4. 兼容性
    • HTML5 History API 在现代浏览器中完全支持
    • IE 10+ 支持,但旧版 IE 支持有限
  5. 最佳实践
    • 总是与 popstate 事件一起使用
    • 确保状态对象是可序列化的(不包含函数、循环引用等)
    • 状态对象大小不宜过大(某些浏览器限制为 640k 字符)
1.6.5 与 window.history 的关系

history 对象是 window 对象的属性,以下两种写法等价:

window.history.back();history.back();

在大多数情况下,可以省略 window. 前缀直接使用 history

2.本地存储

2.1本地存储分类
2.1.1Cookie
  • 特点:

    • 存储大小约4KB

    • 会随HTTP请求自动发送到服务器

    • 可设置过期时间

  • 使用场景:用户身份验证、会话管理

// 设置Cookiedocument.cookie = \"username=John; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/\";// 读取Cookieconst cookies = document.cookie.split(\';\');
2.1.2Web Storage

(1) localStorage

  • 特点:
    • 持久化存储(除非手动清除)
    • 存储大小5-10MB(各浏览器不同)
    • 同源策略限制

(2) sessionStorage

  • 特点:
    • 会话级存储(标签页关闭即清除)
    • 存储大小5-10MB
    • 同源策略限制
// localStorage使用localStorage.setItem(\'theme\', \'dark\');const theme = localStorage.getItem(\'theme\');// sessionStorage使用sessionStorage.setItem(\'tempData\', JSON.stringify({id: 1}));const data = JSON.parse(sessionStorage.getItem(\'tempData\'));
2.1.3IndexedDB
  • 特点:
    • 客户端数据库,存储大量结构化数据
    • 支持事务、索引查询
    • 异步API
  • 使用场景:离线应用、大数据量存储
// 打开/创建数据库const request = indexedDB.open(\'myDatabase\', 1);request.onsuccess = (event) => { const db = event.target.result; // 数据库操作...};
2.1.4Cache API
  • 特点:
    • 用于缓存网络请求响应
    • Service Worker配合使用
  • 使用场景:PWA应用、离线资源缓存
caches.open(\'my-cache\').then(cache => { cache.add(\'/api/data\');});
2.2存储复杂数据类型
2.2.1JSON序列化方法

适用于Web Storage存储对象/数组

const user = { name: \"张三\", preferences: { theme: \"dark\", fontSize: 16 }};// 存储localStorage.setItem(\'user\', JSON.stringify(user));// 读取const storedUser = JSON.parse(localStorage.getItem(\'user\'));
2.2.2IndexedDB存储复杂对象

直接支持存储JavaScript对象

const transaction = db.transaction(\'users\', \'readwrite\');const store = transaction.objectStore(\'users\');store.put({ id: 1, name: \"李四\", tags: [\"vip\", \"admin\"], meta: { lastLogin: new Date() }});
2.2.3特殊数据类型处理

(1) Date对象

// 存储localStorage.setItem(\'lastUpdated\', new Date().toISOString());// 读取const date = new Date(localStorage.getItem(\'lastUpdated\'));

(2) Map/Set

const map = new Map([[\'key1\', \'value1\'], [\'key2\', \'value2\']]);// 存储localStorage.setItem(\'myMap\', JSON.stringify(Array.from(map.entries())));// 读取const mapData = new Map(JSON.parse(localStorage.getItem(\'myMap\')));
2.3实践建议
  1. 数据安全

    • 敏感信息不要存储在客户端
    • 考虑使用加密库对数据进行加密
  2. 容量管理

    // 检查localStorage剩余空间function getLocalStorageRemainingSpace() { const testKey = \'test\'; let data = \'\'; try { // 填充数据直到超出限制 while(true) { data += \'xxxxxxxxxx\'; localStorage.setItem(testKey, data); } } catch (e) { localStorage.removeItem(testKey); return data.length; }}
  3. 错误处理

    try { localStorage.setItem(\'key\', largeData);} catch (e) { if (e.name === \'QuotaExceededError\') { console.error(\'存储空间不足\'); // 清理旧数据或提示用户 }}
  4. 数据版本控制

    const storageVersion = \'v2.1\';if(localStorage.getItem(\'version\') !== storageVersion) { localStorage.clear(); localStorage.setItem(\'version\', storageVersion);}
  5. 性能优化

    • 大数据量优先使用IndexedDB
    • 频繁读写的数据可以先用内存缓存,再批量写入存储
2.4现代存储方案对比
方案 容量 持久性 数据结构 同步/异步 适用场景 Cookie 4KB 可设置 字符串 同步 小数据、身份验证 localStorage 5-10MB 持久 字符串 同步 用户偏好设置 sessionStorage 5-10MB 会话级 字符串 同步 临时数据 IndexedDB ≥250MB 持久 复杂类型 异步 离线应用、大数据 Cache API 动态 持久 请求/响应 异步 网络资源缓存

根据应用需求选择合适的存储方案,对于现代Web应用,通常需要组合使用多种存储技术。

六.正则&阶段案例

1.正则表达式介绍

正则表达式(Regular Expression,简称 regex)是用于匹配字符串中字符组合的模式,它是一种强大的字符串处理工具,主要用于:

  • 字符串搜索
  • 字符串替换
  • 数据验证
  • 字符串提取和分割

在 JavaScript 中,正则表达式通过 RegExp 对象实现,有两种创建方式:

// 字面量形式const regex1 = /pattern/flags;// 构造函数形式const regex2 = new RegExp(\'pattern\', \'flags\');

2.正则表达式语法

2.1. 基础语法
语法 描述 示例 literal 直接匹配字符 /abc/ 匹配 “abc” ` ` 或操作 [] 字符集合 [abc] 匹配 “a”、“b” 或 “c” [^] 否定字符集合 [^abc] 匹配非 “a”、“b”、“c” 的字符 () 分组 (abc)+ 匹配 “abc” 一次或多次
2.2.量词
量词 描述 示例 * 0次或多次 a* 匹配 “”, “a”, “aa”, … + 1次或多次 a+ 匹配 “a”, “aa”, … ? 0次或1次 a? 匹配 “”, “a” {n} 恰好n次 a{2} 匹配 “aa” {n,} 至少n次 a{2,} 匹配 “aa”, “aaa”, … {n,m} n到m次 a{2,4} 匹配 “aa”, “aaa”, “aaaa”
2.3元字符(特殊字符)
元字符 描述 等价字符类 . 匹配除换行符外的任意字符 [^\\n\\r] \\d 数字字符 [0-9] \\D 非数字字符 [^0-9] \\w 单词字符(字母、数字、下划线) [A-Za-z0-9_] \\W 非单词字符 [^A-Za-z0-9_] \\s 空白字符(空格、制表符、换行等) [\\t\\n\\v\\f\\r ] \\S 非空白字符 [^\\t\\n\\v\\f\\r ] \\b 单词边界 - \\B 非单词边界 - ^ 字符串开始 - $ 字符串结束 -
2.3修饰符(标志)
修饰符 描述 示例 i 不区分大小写 /abc/i 匹配 “ABC” g 全局匹配(查找所有匹配) /a/g 在 “aaa” 中找到3个匹配 m 多行模式(^和$匹配每行的开始/结束) /^a/gm 在多行中匹配每行开头的a s 允许.匹配换行符 /a.b/s 匹配 “a\\nb” u Unicode模式(正确处理4字节字符) /\\u{1F600}/u 匹配😀 y 粘性匹配(从lastIndex开始精确匹配) /a/y 从指定位置匹配

3.五个实用案例

案例1:邮箱验证
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/;console.log(emailRegex.test(\'user@example.com\')); // trueconsole.log(emailRegex.test(\'invalid.email@\')); // false
案例2:提取URL中的域名
const url = \'https://www.example.com/path?query=string\';const domainRegex = /^(https?:\\/\\/)?([^\\/\\?]+)/i;const match = url.match(domainRegex);console.log(match[2]); // www.example.com
案例3:密码强度验证
// 至少8字符,包含大小写字母和数字const passwordRegex = /^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[0-9a-zA-Z]{8,}$/;console.log(passwordRegex.test(\'StrongPass1\')); // trueconsole.log(passwordRegex.test(\'weak\')); // false
案例4:格式化电话号码
const phone = \'1234567890\';const formatted = phone.replace(/^(\\d{3})(\\d{3})(\\d{4})$/, \'($1) $2-$3\');console.log(formatted); // (123) 456-7890
案例5:移除HTML标签
const html = \'
Hello World
\';const cleanText = html.replace(/]*>/g, \'\');console.log(cleanText); // Hello World

4.高级技巧

1. 非捕获组
// 使用 (?:...) 表示不捕获的分组const dateRegex = /(\\d{4})-(?:\\d{2})-(\\d{2})/;const dateMatch = \'2023-05-15\'.match(dateRegex);console.log(dateMatch); // [\"2023-05-15\", \"2023\", \"15\"]
2. 回溯引用
// 匹配重复单词const repeatRegex = /\\b(\\w+)\\s+\\1\\b/;console.log(repeatRegex.test(\'hello hello\')); // trueconsole.log(repeatRegex.test(\'hello world\')); // false
3. 正向/负向预查
// 正向肯定预查 (?=...)const hasNumberRegex = /^(?=.*\\d).+$/;// 正向否定预查 (?!...)const noSpecialCharRegex = /^(?!.*[@#$%]).+$/;

5.常见问题解决

1. 贪婪匹配 vs 惰性匹配
const greedyRegex = //; // 匹配整个 
...
const lazyRegex = //; // 只匹配单个标签
2. 多行匹配
const multiLineText = `Line 1Line 2Line 3`;// 不使用m修饰符console.log(/^Line/g.test(multiLineText)); // false// 使用m修饰符console.log(/^Line/gm.test(multiLineText)); // true
3. Unicode字符匹配
// 不使用u修饰符console.log(/^.$/.test(\'😀\')); // false// 使用u修饰符console.log(/^.$/u.test(\'😀\')); // true

正则表达式是JavaScript中非常强大的工具,掌握它可以极大提高字符串处理的效率和灵活性。建议从简单模式开始练习,逐步掌握更复杂的表达式。