Why does JSON.stringify return empty object notation "{}" for an object that seems to have properties?
Asked Answered
B

3

37

The following example shows that JSON.stringify() returns the string "{}" for SpeechSynthesisVoice objects:

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

Complete example: JSFiddle

Why does it return "{}" and not something like "{voiceURI: "Google Deutsch", name: "Google Deutsch", lang: "de-DE", localService: false, default: false}"?

Note that the above example does not work for chrome or iOS; it is targeted for Mozilla Firefox.

Blur answered 23/7, 2016 at 13:22 Comment(0)
C
40

JSON.stringify includes an object's own, enumerable properties (spec) that have values that aren't functions or undefined (as JSON doesn't have those), leaving out ones it inherits from its prototype, any that are defined as non-enumerable, and any whose value is a function reference or undefined.

So clearly, the object you get back from getVoices()[0] has no own, enumerable properties that can be represented in JSON. All of their properties must be either inherited, defined as non-enumerable, or (though it's probably not the case here) functions or undefined.

Corinnecorinth answered 23/7, 2016 at 13:25 Comment(4)
Or properties that are not valid JSON data types, though that's probably not relevant to the question's example.Cuccuckold
Ok, thanks! I have updated the example to show that voice object seems to have some properties like a normal object. How can you see (using the debug view or from the console output) that these properties are inherited?Blur
@MathiasS: When .hasOwnProperty() returns falseBauxite
@MathiasS: It depends on the debugger you're using how inherited properties are displayed. Frequently they're shown as being on a propety on the object called __proto__ or just proto. As slebetman says, in code you can tell by using voiceObject.hasOwnProperty("voiceURI") and such. If it's true, it's an "own" property; if not, it's inherited.Corinnecorinth
L
6

The answer of T.J Crowder works for me, i was creating my object like this:

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

I changed for this and the problem was solved:

Object.defineProperties(completeObj, {
    [attributeName]: {
        value: finalValue,
        enumerable: true
    }
});
Laughry answered 5/8, 2020 at 18:37 Comment(0)
E
2

You can fix this by doing:

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

...but keep in mind the object type will change, if you require that the object is of a specific type.

Edgy answered 15/8, 2019 at 21:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.