浏览器端类似Node.js v8.serialize、支持Map与循环引用的序列化方案咨询
浏览器环境替代Node.js
v8.serialize() 的可行方案 以下方案均可覆盖你提到的三类需求:支持Map/Set等特殊内置类型序列化、兼容任意合法类型的键值、自动处理循环引用。
方案1:原生structuredClone API(无额外依赖,优先推荐)
所有现代浏览器(Chrome 98+、Firefox 94+、Safari 15.4+、Edge 98+)已原生支持该API,底层基于和v8.serialize同源的结构化克隆算法实现,性能远高于第三方实现,开箱即用。
基础用法示例:
// 包含Map、循环引用的测试对象 const target = { x: new Map([[1, "some value"]]), date: new Date(), set: new Set([1,2,3]) }; // 添加循环引用 target.self = target; // 直接得到深拷贝后的完整对象 const cloned = structuredClone(target); console.log(cloned.x.get(1)) // 输出 "some value" console.log(cloned.self === cloned) // 输出 true
如果需要将对象序列化为可传输/存储的二进制格式,可以配合MessageChannel实现:
// 序列化得到ArrayBuffer function serialize(obj) { const { port1, port2 } = new MessageChannel(); return new Promise(resolve => { port1.onmessage = e => resolve(e.data); port2.postMessage(obj); }); }
该API的限制和v8.serialize一致:无法序列化函数、Symbol、自定义类实例等非结构化类型,如有这类需求可以选择方案2。
方案2:第三方轻量库实现(兼容旧浏览器,支持自定义扩展)
如果需要兼容低版本浏览器,或者需要支持自定义类型的序列化规则,可以选择成熟的开源工具:
flatted:体积不足1KB,天生支持循环引用,可自行扩展特殊类型的转换规则
示例用法:import { stringify, parse } from 'flatted'; const target = { x: new Map([[1, "some value"]]) }; target.self = target; // 序列化:自定义Map的转换逻辑 const str = stringify(target, (key, value) => { if (value instanceof Map) return { __type: 'Map', entries: [...value.entries()] }; return value; }); // 反序列化:还原Map const parsed = parse(str, (key, value) => { if (value?.__type === 'Map') return new Map(value.entries); return value; });superjson:预设了Map/Set/BigInt/Date等所有常用内置类型的转换规则,开箱即用不需要写自定义逻辑,也默认支持循环引用处理。
方案3:自定义JSON.stringify钩子(零依赖,适合简单场景)
如果你的场景只有少量特殊类型,也可以自己实现序列化/反序列化的转换函数,零额外依赖:
// 序列化钩子 function replacer() { const visited = new WeakSet(); return (key, value) => { // 处理循环引用 if (typeof value === 'object' && value !== null) { if (visited.has(value)) return '__circular__'; visited.add(value); } // 处理Map类型 if (value instanceof Map) return { __type: 'Map', entries: [...value.entries()] }; // 其他类型比如Set、Date可按相同规则扩展 return value; } } // 反序列化钩子 function reviver(key, value) { if (value?.__type === 'Map') return new Map(value.entries); return value; } // 使用示例 const target = { x: new Map([[1, "some value"]]) }; target.self = target; const str = JSON.stringify(target, replacer()); const parsed = JSON.parse(str, reviver);
内容的提问来源于stack exchange,提问作者Jannchie
相关产品推荐
相关产品推荐

