localStorage.setItem必须传字符串,因其底层仅支持字符串存储,非字符串类型会自动调用toString()导致数据丢失(如对象变"[object Object]");存对象须用JSON.stringify(),取时需JSON.parse()并判空防错。

localStorage.setItem 为什么必须传字符串?
因为 localStorage 底层只接受字符串值,任何非字符串类型(比如对象、数组、数字、布尔)都会被自动调用 toString() 转换——{a:1} 变成 "[object Object]",null 变成 "null",这会导致数据丢失。
正确做法是手动序列化:
- 存对象:用
JSON.stringify()包一层,例如localStorage.setItem("user", JSON.stringify({name:"Alice", id:101})) - 取对象:必须配对用
JSON.parse(),例如const user = JSON.parse(localStorage.getItem("user")) - 注意
JSON.parse(null)会报错,所以建议加空值判断:localStorage.getItem("user") && JSON.parse(...)
怎么安全地“改”一个已存在的 key?
setItem 本身没有“更新”语义,它对已存在 key 的操作就是覆盖。所谓“改”,本质就是重新 setItem 一次。
但容易踩的坑是:直接改原对象再存,却忘了序列化。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
立即学习“前端免费学习笔记(深入)”;
- 错误写法:
let user = JSON.parse(localStorage.getItem("user")); user.name = "Bob"; localStorage.setItem("user", user);→ 这里user是对象,没转字符串,结果存的是"[object Object]" - 正确写法:
localStorage.setItem("user", JSON.stringify(user)); - 如果只是局部字段更新,建议先取、再改、再存,避免漏掉其他字段
removeItem 和 clear 的实际影响范围
removeItem("key") 只删单个键;clear() 会清空当前域名+协议+端口下所有 localStorage 数据——这个动作不可逆,且不触发任何事件。
- 别在生产环境调试时随手
clear(),尤其当多个模块共用同一个域下的 storage(比如管理后台和用户前台混在同一个域名) -
removeItem对不存在的 key 不报错,可放心调用,适合“删除可能不存在的缓存”场景 - 想批量删某些 key(比如带前缀的),得自己遍历:
for (let i = 0; i
5MB 限制不是绝对安全的硬上限
浏览器标称 5–10MB,但实际可用空间受三方面挤压:
- 每个 key 的名称(key 字符串)也计入总容量,长 key 名会快速吃掉额度
- 字符串编码方式影响字节数:中文字符在 UTF-16 下占 2 字节,但
localStorage按 UTF-16 计量,所以存大量中文比英文更快触顶 - Chrome 等浏览器在接近上限时会静默失败——
setItem不抛错,但getItem返回null,需主动检查是否写入成功(比如写完立刻读,比对值)
真正需要存大量结构化数据时,别硬扛,该上 IndexedDB 就上,localStorage 只适合轻量配置、临时状态、小段 JSON 缓存。


















