为啥 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 返回一个空对象 [重复]
在 fabricjs 对象上应用 JSON.stringify 后自定义属性丢失