原型链不参与序列化,JSON.stringify仅处理自有可枚举属性;需手动添加类型标识并用构造函数+Object.assign恢复原型关系。

原型链本身不直接参与序列化,它属于 JavaScript 对象的继承机制;而序列化是把运行时对象转为可存储或传输的格式(如 JSON 字符串、字节流)。所谓“基于原型链的对象序列化工具”,实际是指:在序列化过程中,既要保留对象的结构和数据,又要合理处理原型上定义的方法、不可枚举属性、以及原型链中可能影响序列化行为的特征(比如 toJSON 方法、Symbol 键、循环引用等)。
明确原型与序列化的边界
JavaScript 原生 JSON.stringify() 只序列化对象**自身可枚举的自有属性**,完全忽略原型链上的任何内容——包括方法、getter、setter 和不可枚举属性。这是设计使然,不是缺陷。
- 原型上的方法不会被序列化,也不该被序列化(它们属于行为逻辑,不是状态)
- 若需还原“带原型”的对象,必须在反序列化后手动重建原型关系(例如用
Object.setPrototypeOf()或构造函数) - 直接序列化函数、
undefined、Symbol、Date等类型会丢失或出错,需预处理
支持原型信息的自定义序列化方案
如果业务需要记录原型归属(比如用于调试、服务端还原类型),可在序列化时显式加入类型标识:
- 给目标类添加静态
type属性或constructor.name字段 - 序列化前注入
__protoType__: "Person"类型标记 - 避免直接序列化整个原型对象(会造成无限递归或巨大体积)
- 示例:JSON.stringify({ ...obj, __type: obj.constructor?.name || 'Object' })
安全处理原型链中的特殊行为
某些对象通过原型定义了 toJSON() 方法,这会劫持 JSON.stringify() 的行为:
- 若对象或其原型上有
toJSON(),它会被自动调用并返回结果,原对象其他属性被忽略 - 可临时删除或重命名该方法再序列化,但需谨慎(可能破坏业务逻辑)
- 对 Date、Map、Set 等内置对象,也依赖其原型上的
toJSON实现,无需额外干预
反序列化后恢复原型关系
纯 JSON 无法携带原型信息,所以反序列化后得到的是普通 plain object。要还原“类实例+原型”结构,需结合构造函数:
- 先解析 JSON 得到数据对象
- 用对应构造函数创建新实例:
const inst = new Person() - 用
Object.assign(inst, data)或解构赋值填充属性 - 更健壮的做法:在类中提供静态
fromJSON(json)工厂方法

















