Web Storage 为什么 localStorage 不能保存对象
来源:17golang原创
时间:2026-10-26 05:45:08 283浏览 收藏
localStorage的键和值都是字符串,不能直接保留JavaScript对象结构。把普通对象直接传给setItem,通常会存成[object Object];正确方式是先JSON.stringify,再在读取后JSON.parse,并确认解析结果符合应用需要的结构。
参考文档地址:https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage
触发信号:读回的是字符串而不是配置对象
设想一个文章列表页把主题和每页条数保存为配置,页面刷新后却读不到theme字段。若写入时传的是普通对象,问题往往发生在字符串转换阶段,而不是刷新清除了对象。下面是原创的配置存取场景,未在浏览器执行,也不涉及真实用户信息。
const settings = { theme: "dark", pageSize: 20 };
// 错误示范:setItem会把普通对象转换为字符串。
localStorage.setItem("demo:raw-settings", settings);
const raw = localStorage.getItem("demo:raw-settings");
console.log(typeof raw); // 有值时读回类型为string。
以上错误示范使用独立演示键,说明API的值类型。localStorage不是对象引用仓库;保存以后继续修改内存对象,也不会自动更新已经存进去的文本。

快速判断:区分转换问题和存储不可用
| 信号 | 判断方向 |
|---|---|
| 出现[object Object] | 写入前缺少明确的JSON编码 |
| getItem返回null | 该来源下此键不存在,不代表解析失败 |
| JSON.parse抛SyntaxError | 已保存文本不是合法JSON |
| 访问或写入抛异常 | 检查策略限制、配额与运行环境 |
HTTP与HTTPS、不同主机或端口分别属于不同来源,不能假设它们共用同一份localStorage。file:页面的行为也不应作为正式应用依据。隐私浏览、用户清理数据或存储策略会影响保留行为,不能把无内置过期时间理解为永久可靠备份。
处理步骤:保存JSON并恢复有限字段
示例只保存可重新构造的显示偏好。使用版本字段和固定字段检查,避免把解析出的任意对象直接合并到运行时配置。把以下代码作为页面脚本使用,浏览器需允许当前来源访问Web Storage。
const SETTINGS_KEY = "article-list:settings";
const defaults = () => ({ theme: "light", pageSize: 20 });
function isSettings(value) {
// JSON合法不代表业务结构正确,只接受约定字段类型和范围。
return value !== null && typeof value === "object"
&& !Array.isArray(value) && value.version === 1
&& ["light", "dark"].includes(value.theme)
&& [10, 20, 50].includes(value.pageSize);
}
function readSettings() {
try {
const raw = localStorage.getItem(SETTINGS_KEY);
if (raw === null) return { value: defaults(), reason: "missing" };
const parsed = JSON.parse(raw);
if (!isSettings(parsed)) {
return { value: defaults(), reason: "unsupported-data" };
}
// 重新构造需要的字段,不复用或合并不可信额外属性。
return {
value: { theme: parsed.theme, pageSize: parsed.pageSize },
reason: "loaded",
};
} catch (error) {
return {
value: defaults(),
reason: error instanceof SyntaxError ? "invalid-json" : "read-failed",
};
}
}
function saveSettings(value) {
const payload = {
version: 1, theme: value?.theme, pageSize: value?.pageSize,
};
if (!isSettings(payload)) {
return { ok: false, reason: "invalid-settings" };
}
try {
// 编码与写入都放入异常边界;只持久化有限的普通字段。
localStorage.setItem(SETTINGS_KEY, JSON.stringify(payload));
return { ok: true };
} catch (error) {
return { ok: false, reason: error.name || "write-failed" };
}
}
const saved = saveSettings({ theme: "dark", pageSize: 50 });
const restored = readSettings();
console.log(saved.ok, restored.reason, restored.value.theme);
在允许写入且期间没有其他页面改动该键的情况下,预期最后得到true、loaded、dark。这里提供的是推导出的结果判断,不是实测日志。写入失败时仍可在内存里应用用户所选偏好,但界面应说明“本次设置未持久化”,不要给出已保存的假反馈。
JSON只能保留相应的数据表示:Date通常变为字符串,方法和原型不会自动恢复,Map、Set也不会直接变为可用的原类型。对象中的undefined属性通常被省略,数组中的相应位置可能变为null;循环引用与默认处理的BigInt可使stringify抛错。示例因此只保存有限字符串和整数。

回退路径:只重置自己的配置键
对于损坏或版本不支持的偏好,先使用默认值保证页面可读,再由明确的重置操作删除本应用的单个键。读取函数不自动覆写旧值,这样未知版本不会被旧页面悄悄销毁。若需要版本迁移,应识别旧结构后转换,最后再保存新版本。
function resetSettings() {
try {
// 只删除当前配置,不用clear清空同来源其他功能的数据。
localStorage.removeItem(SETTINGS_KEY);
return { ok: true, value: defaults() };
} catch (error) {
return { ok: false, reason: error.name || "reset-failed" };
}
}
不要对整个来源直接调用clear作为默认修复,它可能连带删除其他功能的本地状态。重要业务数据需要独立可靠的保存方案,不能把重置偏好的操作套用到未备份的用户草稿。
结果确认:类型、版本与失败原因分别记录
排查顺序是先看读取值是否为null,再看文本是否合法JSON,随后看版本与字段是否可接受,最后确认是否发生访问或写入异常。对外提示区分“首次使用默认值”“配置无法恢复”“保存失败”,诊断记录只保存原因码,不打印完整用户数据。
localStorage操作是同步的,较大对象的编码和写入可能阻塞页面,因此适合少量配置,不应每次输入都同步存整份大型文档。多个标签页对同一个键读改写也不构成完整事务,不能把一次setItem等同于多步骤更新具备并发保护。
解析后修改对象会自动保存吗?
不会。修改的是内存对象,仍需重新编码并调用setItem。
存入JSON的null与键不存在一样吗?
不同。键不存在时getItem直接返回null;保存文本null时,先读到字符串,再经JSON.parse得到JavaScript null,结构检查应单独处理。
JSON.stringify能加密数据吗?
不能,它只编码。不要把敏感凭据当作普通偏好存入此示例,当前来源可执行的脚本可以访问相应存储。
-
306 收藏
-
194 收藏
-
427 收藏
-
480 收藏
-
486 收藏
-
157 收藏
-
352 收藏
-
139 收藏
-
218 收藏
-
492 收藏
-
366 收藏
-
273 收藏
-
406 收藏
-
471 收藏
-
148 收藏
-
文章 · 前端 | 12小时前 | 前端 · javascript · 浏览器API · AbortController AbortSignal JavaScript异步任务 scheduler.postTask304 收藏
-
234 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习