localstorage只能存字符串,存数组或对象会转成"[object object]";须用json.stringify()存、json.parse()取,并加try/catch防错;动态更新应封装原子操作函数避免竞态;文件下载需blob+createobjecturl,设正确type防乱码;老浏览器需检测localstorage可用性并降级;多标签页需监听storage事件处理冲突。

为什么 localStorage 不能直接存数组或对象
因为 localStorage 只接受字符串作为值,存任何非字符串类型(比如 []、{}、null)都会被自动转成 "[object Object]" 或 "",取出来就废了。
- 常见错误现象:
localStorage.setItem('todos', [{id:1, text:'buy milk'}])→ 取出是"[object Object]" - 正确做法:存之前必须用
JSON.stringify(),读之后必须用JSON.parse() - 注意
JSON.parse()对空值或损坏字符串会抛错,建议加try/catch - 示例:
const todos = [{id:1, text:'buy milk'}];<br>localStorage.setItem('todos', JSON.stringify(todos));<br><br>let saved = localStorage.getItem('todos');<br>const parsed = saved ? JSON.parse(saved) : [];
动态增删 todo 时,如何避免覆盖或丢失数据
每次写入都该基于当前最新状态做操作,而不是“读→改→写”三步手动拼接——尤其在多标签页或快速点击场景下极易出错。
- 不要这样:
const list = getFromStorage(); list.push(newItem); saveToStorage(list);(竞态风险) - 推荐封装一个原子操作函数,比如
updateTodos((current) => [...current, newItem]) -
updateTodos内部统一处理读取、转换、更新、保存,确保单点控制 - 删除时别用
filter后全量重写,除非你确认数据量小;大列表可考虑用 ID 索引缓存提升响应
文件自动保存到本地(.json)为什么浏览器不支持直接写磁盘
浏览器出于安全限制,无法像 Node.js 那样调用 fs.writeFile,所谓“自动保存”其实是触发下载,由用户选择路径和确认。
- 核心方法是构造
Blob+URL.createObjectURL+<a download></a>模拟点击 - 容易踩的坑:
Blob类型必须显式设为"application/json;charset=utf-8",否则中文乱码 - 不要用
location.href = 'data:...'方案,iOS Safari 不支持长 data URL 下载 - 示例:
const blob = new Blob([JSON.stringify(todos, null, 2)], {<br> type: 'application/json;charset=utf-8'<br>});<br>const url = URL.createObjectURL(blob);<br>const a = document.createElement('a');<br>a.href = url;<br>a.download = 'todos.json';<br>a.click();<br>URL.revokeObjectURL(url);
IE11 或旧版 Safari 下 localStorage 读写失败怎么办
不是所有老浏览器都完整支持 localStorage,更别说 JSON.stringify 对循环引用或 undefined 的处理差异。
- 先检测可用性:
try { localStorage.test = 1; delete localStorage.test; } catch(e) { /* fallback */ } - IE11 会把
undefined序列化成null,但某些版本对Date或RegExp直接报错,todo 列表里尽量只存 plain object - 兼容方案可降级到
cookie(容量小)或内存暂存 + 提示“请升级浏览器” - 真正要长期存且跨设备,别依赖前端存储,得连后端 API
实际用起来最麻烦的不是存和取,而是当用户在 A 标签页添加、B 标签页同时删除时,怎么让两边状态不打架。这问题没银弹,得靠事件监听 storage 事件 + 合理的冲突策略,比如“以最后修改为准”或“提示用户手动合并”。










