Web Storage 为什么 localStorage 不能保存对象
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能加密数据吗?
不能,它只编码。不要把敏感凭据当作普通偏好存入此示例,当前来源可执行的脚本可以访问相应存储。
CSS line-clamp 怎样把多行文本限制在固定行数
- 上一篇
- CSS line-clamp 怎样把多行文本限制在固定行数
- 下一篇
- Vite import.meta.glob 怎样批量加载模块
-
- 文章 · 前端 | 59分钟前 |
- Vite import.meta.glob 怎样批量加载模块
- 157浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSS line-clamp 怎样把多行文本限制在固定行数
- 352浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- IntersectionObserver 怎样实现列表图片进入视口再加载
- 139浏览 收藏
-
- 文章 · 前端 | 1小时前 | javascript · ArrayBuffer TypedArray Transferable Web Workers
- Web Workers 怎样用 transferable 减少数组复制
- 218浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端 · javascript · Fetch 流式读取 ReadableStream TextDecoder Response.Body
- Fetch Response.body 怎样逐块读取文本流
- 492浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSS transition-behavior 怎样让 display 切换也参与过渡
- 366浏览 收藏
-
- 文章 · 前端 | 1小时前 | JavaScript 请求超时 Fetch AbortController AbortSignal.timeout
- JavaScript AbortSignal.timeout 怎样取消超时请求
- 273浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端 · css · CSS 中文排版 text-spacing-trim CJK 标点间距
- CSS text-spacing-trim 怎样处理 CJK 标点两侧空隙
- 406浏览 收藏
-
- 文章 · 前端 | 1小时前 |
- CSS scroll-snap 怎样让横向列表停在卡片边缘
- 471浏览 收藏
-
- 文章 · 前端 | 1小时前 | 前端 · css · CSS 容器查询 响应式组件 container-type
- CSS container-type 怎样让组件按容器尺寸响应
- 148浏览 收藏
-
- 文章 · 前端 | 12小时前 | 前端 · javascript · 浏览器API · AbortController AbortSignal JavaScript异步任务 scheduler.postTask
- scheduler.postTask 取消尚未执行任务的处理方案
- 304浏览 收藏
-
- 文章 · 前端 | 15小时前 | 前端 · css · 浏览器API · CSSNumericValue CSS Typed OM CSSUnitValue
- CSSNumericValue 怎样在兼容单位之间转换数值
- 234浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 698次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 708次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 777次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 739次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 572次使用
-
- Go Goja 怎么预编译脚本并在多个运行时执行
- 2026-10-13 306浏览
-
- 这样需求的表单一般要这么做?
- 2023-02-17 194浏览
-
- css 中的px 跟 video 中px 等同吗?
- 2023-01-09 427浏览
-
- 为什么使用了https还是可以被抓包
- 2023-02-16 480浏览
-
- 无法控制Websocket的send和receive事件
- 2023-02-16 486浏览

