Почему JSON.stringify возвращает пустое обозначение объекта "{}" для объекта, который, как представляется, имеет свойства?

В следующем примере показано, что 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.

Ответ 2

Вы можете исправить это, выполнив:

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

... но имейте в виду, что тип объекта изменится, если вам потребуется, чтобы объект был определенного типа.