json.stringify()默认只序列化对象自身的可枚举属性,自动忽略原型链上所有属性;若属性被显式赋值到实例则成为自有属性而被包含,此时需用replacer函数或hasownproperty等方法手动过滤。

JavaScript 序列化(如 JSON.stringify())默认只处理对象自身的可枚举属性,**自动忽略原型链上的所有属性**,包括原型对象上的自有属性和方法。所以你通常不需要额外操作来“忽略”原型属性——它本来就不会被序列化。
为什么原型属性不会出现在 JSON 中
JSON.stringify() 的行为规范明确要求:只遍历并序列化目标对象的自身可枚举属性(own enumerable properties)。原型链上的属性(无论是否可枚举)均被跳过。例如:
const Parent = { name: 'Parent', say() { return 'hi'; } };
const child = Object.create(Parent);
child.id = 123;
child.title = 'Hello';
console.log(JSON.stringify(child)); // {"id":123,"title":"Hello"}
// ✅ 没有出现 name 或 say —— 原型属性天然被忽略
需警惕的例外情况:属性被“拷贝到实例上”
如果原型上的属性被显式赋值到实例自身(比如通过 child.name = 'xxx'),那它就变成了实例的自有属性,JSON.stringify() 就会包含它。此时若想排除,需手动过滤:
- 使用
Object.keys()获取自有可枚举键,再按需筛选 - 用
Object.getOwnPropertyDescriptors()结合propertyIsEnumerable判断 - 或在
JSON.stringify()第二个参数(replacer)中控制字段
主动控制序列化字段(replacer 方式)
若需精细控制(比如排除某些自有属性,或确保不包含动态添加的原型代理属性),可用 replacer 函数:
const obj = { id: 1, secret: 'abc', __proto__: { hidden: 'nope' } };
JSON.stringify(obj, (key, value) => {
if (key === 'secret') return undefined; // 过滤自有属性
return value;
});
// → {"id":1}
// 注意:hidden 仍不会出现,因它不在 obj 自身属性中
检查属性是否属于实例自身
调试时可快速验证某个属性是否会被序列化:
-
obj.hasOwnProperty('prop')→ 是自有属性? -
Object.prototype.propertyIsEnumerable.call(obj, 'prop')→ 是否可枚举? -
Reflect.ownKeys(obj)→ 获取所有自有键(含不可枚举 Symbol)
只有同时满足“自有 + 可枚举”的属性,才会进入 JSON.stringify() 的输出。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











