localStorage只支持字符串,存对象需JSON.stringify(),读取需JSON.parse()并try/catch;UI更新须先改DOM再存localStorage;推荐分key存储,Safari无痕模式需兜底降级。
localStorage.setItem 保存设置时值被转成字符串
localstorage 只支持字符串,直接存对象或布尔值会导致 json.stringify 被忽略,下次读出来是 "[object object]" 或 "true" 这种不可用的字符串。
- 必须手动序列化:用
JSON.stringify()包一层再存,比如localStorage.setItem('theme', JSON.stringify({ dark: true })) - 读取时必须反序列化:用
JSON.parse(),且要加try/catch——空值、损坏 JSON 会直接报SyntaxError - 别用
localStorage.theme = {...}这种赋值写法,它会隐式调用.toString(),结果一定是错的
用户切换主题后 localStorage 没更新,页面刷新才生效
这是因为 UI 状态(如 class 切换、CSS 变量赋值)和 localStorage 是两套逻辑,保存成功不等于界面已响应。
- 先改 DOM / CSS:比如给
document.documentElement加darkclass,再调用localStorage.setItem - 不要在保存后再去读取 localStorage 触发重绘——直接用当前状态更新界面,避免多一次异步读取延迟
- 如果用了 React/Vue,确保 state 更新和 localStorage 同步:state 改了 → 界面重绘 → 再存 localStorage,顺序不能反
多个设置项共用一个 key 还是分 key 存?
分 key 更灵活、更安全。全塞进一个 userSettings 对象里看似整洁,但实际容易出问题。
- 单 key(如
localStorage.setItem('settings', JSON.stringify(obj))):每次修改任一字段都要全量读-改-写,竞态下易丢数据 - 分 key(如
theme、fontSize、autoSave):原子操作,互不影响;调试时也能快速定位哪个键异常 - 例外情况:如果设置项之间强耦合(比如暗色模式开启时字体大小默认 +1),那可以合并在一个 key 里,但必须用函数封装读写逻辑,避免散落各处
localStorage 在 Safari 无痕模式下直接抛 QuotaExceededError
这不是代码写错了,是 Safari 无痕模式把 localStorage 容量设为 0,任何 setItem 都会失败。
- 必须加兜底:写之前先
try { localStorage.setItem('test', 'x') } catch (e) { /* 降级到内存存储 */ } - 别只检查
typeof localStorage !== 'undefined'——Safari 无痕下它存在但不可用 - 用户设置面板首次加载时,建议统一初始化所有偏好项到内存对象,后续读写都走这个对象,仅在可用时同步到 localStorage
真正麻烦的不是存不存得进去,而是「什么时候该放弃 localStorage」——比如用户刚关掉所有 cookie、开了隐私浏览、又禁了 JS,这时候还硬要存,反而让设置面板卡住或报错。留一条安静的退路比强行一致更重要。

















