IndexedDB原生支持直接存储结构化克隆可序列化的JavaScript对象(如Object、Array、Date、Blob等),无需JSON转换;不支持函数、Promise、Symbol等;键路径或自增主键可自动提取/生成主键;读取时自动还原类型与嵌套结构。

IndexedDB 原生支持直接存储 JavaScript 对象(包括数组、Date、RegExp、Blob、File、ArrayBuffer 及其视图等),**无需手动 JSON.stringify / parse**——只要对象是“结构化克隆可序列化”的,浏览器会自动处理序列化与反序列化。
哪些对象能直接存?
IndexedDB 使用 Structured Clone Algorithm,支持:
- 普通对象、数组、Map、Set、TypedArray(如 Uint8Array)、DataView
- Date、RegExp、Boolean、Number、String、null、undefined(注意:undefined 存入后读出为 null)
- Blob、File、ArrayBuffer(含 SharedArrayBuffer 在部分浏览器受限)
- 嵌套结构(如
{ user: { name: 'Alice', scores: [95, 87] }, avatar: new Blob([...]) })
不支持:函数、Promise、Symbol、WeakMap、WeakSet、DOM 节点、循环引用对象(会报 DataCloneError)。
创建对象仓库时注意键路径与自动填充
定义 schema 时,若对象有唯一标识字段(如 id),可设为 keyPath,写入时无需额外传 key:
立即学习“Java免费学习笔记(深入)”;
const objectStore = db.createObjectStore('users', { keyPath: 'id' });
// ✅ 直接存对象,id 字段自动提取为主键
objectStore.add({ id: 101, name: 'Bob', joined: new Date() });
若没自然键,可用 { autoIncrement: true } 启用自增主键,对象仍原样存:
const store = db.createObjectStore('logs', { autoIncrement: true });
store.add({ level: 'warn', message: 'Timeout', timestamp: Date.now() });
// 主键由 IndexedDB 自动分配,对象内容完整保留
读取时对象自动还原,保持类型和嵌套结构
通过 get()、getAll() 等获取的数据,是完整重建的 JS 对象:
const request = objectStore.get(101);
request.onsuccess = function () {
const user = request.result;
console.log(user.name); // 'Bob'
console.log(user.joined instanceof Date); // true ✅
console.log(user.joined.toISOString()); // 正常输出
};
即使对象含 Uint8Array 或 Blob,也原样返回(注意:Blob 在跨 origin 或私密模式下可能受限制)。
常见陷阱与应对
-
Date 对象存取正常,但不要依赖
toString()或toJSON()—— IndexedDB 内部按时间戳存储,还原为标准 Date 实例。 -
循环引用会立即报错:存前可用
structuredClone(obj)测试是否可克隆(现代浏览器支持),或用第三方库检测循环。 - 大型 ArrayBuffer 或 Blob 不触发内存暴涨:IndexedDB 底层按引用或流式处理,不是深拷贝到 JS 堆,适合存图片、音频片段等。
-
事务完成前勿修改已传入的对象:虽然 IndexedDB 克隆数据,但若在
add()后立刻改obj.name = 'New',不影响已提交值 —— 安全,但逻辑上建议避免混淆。


















