json不能直接存localstorage,需用stringify序列化、parse反序列化;但原生方法不支持date、regexp等类型,须自定义replacer/reviver函数处理,并捕获异常。

JavaScript 中 JSON 本身不能直接存入 localStorage,因为 localStorage 只支持字符串类型。要存取复杂结构化对象(如嵌套对象、数组、日期、函数等),必须先将其序列化为 JSON 字符串再保存;读取时再反序列化还原。但要注意:JSON 标准不支持函数、undefined、Date、RegExp、Symbol、BigInt 等类型,原生 JSON.stringify 和 JSON.parse 会丢失或报错。
基础存取:只含可序列化字段的对象
如果对象只包含字符串、数字、布尔值、null、普通对象、数组等 JSON 安全类型,可直接使用:
-
存:
localStorage.setItem('key', JSON.stringify(obj)) -
取:
JSON.parse(localStorage.getItem('key'))(需加try/catch防止解析失败)
处理 Date、RegExp 等特殊类型
原生 JSON 不保留类型信息。例如 new Date() 会被转成 ISO 字符串,JSON.parse 后是字符串而非 Date 实例。解决方案是自定义序列化/反序列化逻辑:
- 存前用
JSON.stringify(obj, (key, val) => val instanceof Date ? { $date: val.toISOString() } : val) - 取后用
JSON.parse(str, (key, val) => val?.$date ? new Date(val.$date) : val) - 类似方式可扩展支持
RegExp(存{ $regex: pattern, $flags: flags })、Map/Set(转为数组)等
避免 undefined、函数、循环引用导致的错误
JSON.stringify 遇到 undefined、函数、Symbol 会自动忽略对应键;遇到循环引用直接抛错。建议在存储前做预处理:
- 用
JSON.stringify(obj, (k, v) => v === undefined ? null : v)把undefined统一转为null - 提前检测循环引用(可用 WeakMap 记录已遍历对象)
- 函数字段应显式剔除:
JSON.stringify(obj, (k, v) => typeof v === 'function' ? undefined : v)
封装一个健壮的本地存储工具函数
推荐封装一个带错误处理和类型恢复能力的工具:
const safeLocalStorage = {
set(key, value) {
try {
const str = JSON.stringify(value, (k, v) => {
if (v instanceof Date) return { $date: v.toISOString() };
if (v instanceof RegExp) return { $regex: v.source, $flags: v.flags };
if (typeof v === 'function') return undefined;
return v;
});
localStorage.setItem(key, str);
} catch (e) {
console.error('localStorage set failed:', e);
}
},
get(key) {
try {
const str = localStorage.getItem(key);
if (!str) return null;
return JSON.parse(str, (k, v) => {
if (v?.$date) return new Date(v.$date);
if (v?.$regex) return new RegExp(v.$regex, v.$flags);
return v;
});
} catch (e) {
console.error('localStorage get failed:', e);
return null;
}
}
};
// 使用示例
safeLocalStorage.set('user', { name: 'Alice', joined: new Date(), pattern: /abc/g });
const data = safeLocalStorage.get('user'); // { name: 'Alice', joined: Date, pattern: /abc/g }
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











