json.stringify 默认只序列化对象自身的可枚举属性,不遍历原型链;因其内部基于[[ownpropertykeys]]和可枚举性检查,跳过原型上所有属性,无论是否可枚举。

JSON.stringify 默认就只序列化对象自身的可枚举属性,不会遍历原型链上的属性。这是它的内置行为,不需要额外处理。
为什么原型链属性不会被序列化?
因为 JSON.stringify 内部调用的是对象的 Object.keys() 类似逻辑(实际是通过内部抽象操作 [[OwnPropertyKeys]] + 可枚举性检查),只访问对象自身的、enumerable: true 的属性。原型上的方法或属性,哪怕可枚举,也不会被包含。
比如:
const parent = { fromParent: 'yes', method() {} };
const child = Object.create(parent);
child.ownProp = 'only me';
console.log(JSON.stringify(child));
// {"ownProp":"only me"} —— fromParent 和 method 都没出现
注意几个关键点:
- 即使你在原型上定义了
enumerable: true的属性,它依然不会被序列化 -
Object.defineProperty(obj, 'x', { value: 1, enumerable: true })定义在实例上 → 会被序列化 -
Object.defineProperty(Parent.prototype, 'y', { value: 2, enumerable: true })→ 不会被 child 序列化 - getter/setter 若没有对应可枚举的数据属性,且 getter 返回值不是基本类型或可序列化结构,也可能不体现(取决于 getter 执行结果)
如果你发现“原型属性被序列化”了,常见原因有:
- 对象本身通过
Object.assign(child, parent)或展开语法把原型属性拷贝成了自身属性 - 使用了自定义
toJSON()方法,且该方法显式返回了原型数据 - 用了第三方序列化库(如
flatted、serialize-javascript),它们行为不同
想确认某个属性是否属于自身、是否可枚举,可以这样检查:
Object.hasOwn(obj, 'key') && obj.propertyIsEnumerable('key')
只要这个表达式为 true,JSON.stringify 就会包含它;否则,无论原型多深,都不会出现。
所以你不需要写额外代码来“过滤原型链”,只要确保数据存在实例上、且可枚举,JSON.stringify 就按预期工作。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











