为啥 JSON.stringify 为似乎具有属性的对象返回空对象表示法“”?

Posted

技术标签:

【中文标题】为啥 JSON.stringify 为似乎具有属性的对象返回空对象表示法“”?【英文标题】:Why does JSON.stringify return empty object notation "" for an object that seems to have properties?为什么 JSON.stringify 为似乎具有属性的对象返回空对象表示法“”? 【发布时间】:2016-11-27 06:59:19 【问题描述】:

以下示例显示 JSON.stringify() 为 SpeechSynthesisVoice 对象返回字符串 ""

var voiceObject = window.speechSynthesis.getVoices()[0];
JSON.stringify(voiceObject); //returns ""?

完整示例:JSFiddle

为什么它返回"" 而不是"voiceURI: "Google Deutsch", name: "Google Deutsch", lang: "de-DE", localService: false, default: false"

请注意,上面的示例不适用于 chrome 或 ios;它针对 Mozilla Firefox。

【问题讨论】:

【参考方案1】:

JSON.stringify 包括一个对象的自己的、可枚举的 属性 (spec),这些属性的值不是函数或 undefined(因为 JSON 没有这些),省略了它继承自它的原型,任何被定义为不可枚举的,以及任何其值为函数引用或undefined的。

很明显,您从getVoices()[0] 返回的对象没有可以用 JSON 表示的自己的、可枚举的属性。它们的所有属性都必须是继承的、定义为不可枚举的,或者(尽管这里可能不是这种情况)函数或undefined

【讨论】:

或不是有效 JSON 数据类型的属性,尽管这可能与问题的示例无关。 好的,谢谢!我更新了示例以显示语音对象似乎具有一些属性,例如普通对象。您如何(使用调试视图或从控制台输出)看到这些属性是继承的? @MathiasS: 当.hasOwnProperty() 返回假时 @MathiasS:这取决于您使用的调试器如何显示继承的属性。它们经常显示为位于名为__proto__ 或只是proto 的对象上的属性上。正如 slebetman 所说,在代码中你可以通过使用 voiceObject.hasOwnProperty("voiceURI") 等来判断。如果它是真的,它是一个“自己的”财产;如果不是,它是继承的。【参考方案2】:

您可以通过以下方式解决此问题:

var voiceObject = window.speechSynthesis.getVoices()[0];
var newvoiceObject = $.extend(newvoiceObject,voiceObject);
JSON.stringify(newvoiceObject); //returns correct JSON string

...但请记住,如果您要求对象是特定类型,对象类型会发生变化。

【讨论】:

【参考方案3】:

T.J Crowder 的答案对我有用,我正在像这样创建我的对象:

Object.defineProperties(completeObj, 
    [attributeName]: 
        value: finalValue
    
);

为此我改了,问题解决了:

Object.defineProperties(completeObj, 
    [attributeName]: 
        value: finalValue,
        enumerable: true
    
);

【讨论】:

以上是关于为啥 JSON.stringify 为似乎具有属性的对象返回空对象表示法“”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 TypeError 上的 JSON.stringify 返回一个空对象 [重复]

深度使用JSON.stringify()

在 fabricjs 对象上应用 JSON.stringify 后自定义属性丢失

JSON序列化(stringify)对象时排除某些属性的两种方法

JSON.stringify使用

JSON.stringify() 的使用