首先给出核心结论:localStorage 是浏览器内置的轻量级持久化存储方案,容量约 5 MB,仅支持字符串格式。如果存入对象或数组,必须先通过 JSON.stringify() 进行序列化,读取后则使用 JSON.parse() 还原。写入时可能触发配额超限异常,读取时也可能因数据损坏导致解析失败——因此封装一个带容错处理的工具函数是非常有必要的。它严格遵守同源策略,即使关闭浏览器数据也不会清空,但切勿存储敏感信息(如 token 等)。

本质上,localStorage 最适用的场景包括用户偏好设置、表单草稿、开关状态等非敏感数据。操作虽然直观,但必须留意类型转换与容量限制——通常约 5 MB,看似充足,但存储几张较大图片就会立即超限。
基础写入与读取
由于 localStorage 仅接受字符串类型,存储对象或数组前必须先用 JSON.stringify() 序列化,读取时再用 JSON.parse() 还原。这一过程类似行李打包:先压缩为字符串,抵达后再解压才能正常使用。
- 存数据:
localStorage.setItem('theme', 'dark')或localStorage.setItem('user', JSON.stringify({id: 1, name: 'Alice'})) - 取数据:
const theme = localStorage.getItem('theme')或const user = JSON.parse(localStorage.getItem('user') || '{}') - 删除单个项:
localStorage.removeItem('theme') - 清空全部:
localStorage.clear()
封装一个安全的工具函数
直接调用原生 API 容易踩坑:存储空间不足时会抛出 QuotaExceededError,读取时若数据损坏,JSON.parse 也可能导致脚本崩溃。因此建议包装一层带容错处理的辅助函数——写入时捕获异常,提示用户或执行降级策略;读取时使用 try...catch 包裹,避免整个脚本中断;同时最好支持默认值,例如 get('count', 0) 返回数字 0 而非 null。这样一来,代码的健壮性与可维护性都会显著提升。
注意作用域与生命周期
localStorage 遵循同源策略:协议、域名、端口完全一致才能共享数据。关闭标签页或浏览器后数据依然保留,除非手动清除,或浏览器在无痕模式、存储空间不足时自动回收。
- 不同子域名(
app.example.com与api.example.com)无法互相访问 - HTTP 与 HTTPS 被视为不同源,数据不互通
- 移动端 WebView 的行为与桌面浏览器基本一致,但部分安卓旧版 WebKit 存在兼容性问题
替代方案与适用边界
localStorage 并非万能的存储方案。敏感信息(如 token)应交给 httpOnly Cookie 或内存变量;需要频繁读写的复杂状态,推荐使用 IndexedDB;如果需要跨标签页监听数据变化,可以搭配 storage 事件:window.addEventListener('storage', e => console.log(e.key, e.newValue))。
总之,选择合适的工具才能事半功倍,localStorage 适用于简单的持久化需求,复杂场景则不必勉强。
