localStorage 仅支持字符串,存对象需 JSON.stringify(),取时用 JSON.parse()并加 try-catch 防解析失败;读取前须判 null/ 空串;无自动过期机制,需手动加时间戳校验。
localStorage.setItem 保存字符串,不是对象
直接 localstorage.setitem('key', {a: 1}) 会存成 [object object],取出来就是个空字符串。因为 localstorage 只接受字符串值,其他类型都会被隐式转成字符串。
实操建议:
- 存对象前必须用
JSON.stringify(),比如localStorage.setItem('user', JSON.stringify({name: 'Alice'})) - 取的时候用
JSON.parse(),但要加 try-catch——万一数据损坏或被手动改过,JSON.parse()会直接报SyntaxError - 不要存函数、undefined、Date 对象、RegExp 等无法被 JSON 序列化的值,它们会被静默丢掉
读取时检查 null 和解析失败
localStorage.getItem('missing') 返回的是 null,不是 undefined,直接 JSON.parse(null) 会抛错,而不是返回 null。
实操建议:
- 先判断是否为
null或空字符串:const raw = localStorage.getItem('config'); if (!raw) return defaultConfig; - 再尝试解析:
try {return JSON.parse(raw); } catch (e) {return defaultConfig;} - 别省略这个检查——用户可能清过浏览器缓存,或你在开发时手动删过键值
localStorage 没有自动过期机制
它不像 cookie 那样支持 max-age 或 expires,一旦写入,就一直存在,除非主动删、用户清记录、或浏览器判定为“不常访问”而自动清理(某些 iOS 版本 Safari 会这么做)。
立即学习 “ 前端免费学习笔记(深入)”;
实操建议:
- 需要时效性的状态(比如 token、临时表单草稿),自己加时间戳字段:
{value: ……, expires: Date.now() + 1000 * 60 * 60 } - 读取时先校验
expires,过期就删掉并返回默认值:if (data.expires - 别依赖 localStorage 做权限控制——它完全可被用户修改,只适合存 UI 状态、折叠面板开关这类无害信息
跨 tab 同步要用 storage 事件监听
在一个 tab 里调用 localStorage.setItem(),其他同源 tab 不会自动更新变量,也不会触发 Vue/React 的响应式更新。
实操建议:
- 在关键入口(如组件挂载时)主动读一次,确保初始状态准确
- 监听
window.addEventListener('storage', handler),注意:该事件只在「其他 tab」修改时触发,当前 tab 修改不会触发自己 - 事件回调里的
event.key和event.newValue是可用的,但event.oldValue在 Chrome 中有时是null,别依赖它做回滚
最常被忽略的其实是存储容量限制:多数浏览器上限是 5MB 左右,但它是按域名算的,不是每个 key 单独算;一旦超限,setItem 会直接抛 QuotaExceededError 异常——连 catch 都不容易想到要加。