我正在使用JavaScript将对象序列化为JSON字符串,
我注意到只有可枚举的对象属性被序列化了:
var a = Object.create(null,{
x: { writable:true, configurable:true, value: "hello",enumerable:false },
y: { writable:true, configurable:true, value: "hello",enumerable:true }
});
document.write(JSON.stringify(a)); //result is {"y":"hello"}
[pen]
我想知道为什么会这样?我搜索了MDN page,json2解析器文档。 我无法在任何地方找到这种行为。
我怀疑这是使用for... in
个only go through [[enumerable]]属性循环的结果(至少在json2
的情况下)。这可以通过Object.getOwnPropertyNames
之类的东西来完成,它返回可枚举和不可枚举的属性。
但序列化可能会有问题(由于反序列化)。
TL;博士
JSON.stringify
仅序列化可枚举属性?答案 0 :(得分:9)
它在ES5 spec中指定。
如果Type(value)是Object,并且IsCallable(value)是false
If the [[Class]] internal property of value is "Array" then
Return the result of calling the abstract operation JA with argument value.
Else, return the result of calling the abstract operation JO with argument value.
那么,让我们看一下JO。以下是相关部分:
设K是一个内部字符串列表,由 [[Enumerable]]属性为真的所有属性值组成。字符串的顺序应与Object.keys标准内置函数使用的顺序相同。
答案 1 :(得分:0)
正如@ThiefMaster回答的那样,它是在规范中指定的
但是,如果您知道要提前序列化的不可枚举属性的名称,则可以通过将替换函数作为第二个参数传递给JSON.stringify()(documentation on MDN ),就像这样
var o = {
prop: 'propval',
}
Object.defineProperty(o, 'propHidden', {
value: 'propHiddenVal',
enumerable: false,
writable: true,
configurable: true
});
var s = JSON.stringify(o, (key, val) => {
if (!key) {
// Initially, the replacer function is called with an empty string as key representing the object being stringified. It is then called for each property on the object or array being stringified.
if (typeof val === 'object' && val.hasOwnProperty('propHidden')) {
Object.defineProperty(val, 'propHidden', {
value: val.propHidden,
enumerable: true,
writable: true,
configurable: true
});
}
}
return val;
});
console.log(s);