Почему JSON.stringify не выполняет свойства экранного объекта, которые являются функциями?

Почему JSON.stringify () не отображает prop2?

var newObj = {
  prop1: true,
  prop2: function(){
    return "hello";
  },
  prop3: false
};

alert( JSON.stringify( newObj ) ); // prop2 appears to be missing

alert( newObj.prop2() ); // prop2 returns "hello"

for (var member in newObj) {
    alert( member + "=" + newObj[member] ); // shows prop1, prop2, prop3
}

JSFIDDLE: http://jsfiddle.net/egret230/efGgT/


person egret    schedule 23.05.2012    source источник
comment
@BrandtSolovij: Функции - это объекты: попробуйте запустить (function() {}) instanceof Object   -  person Eric    schedule 24.05.2012


Ответы (3)


Поскольку JSON не может хранить функции. Согласно спецификации, значение должно быть одним из:

Допустимые значения JSON
(источник: json.org)


В качестве примечания, этот код сделает функции, замеченные JSON.stringify:

Function.prototype.toJSON = function() { return "Unstorable function" }
person Eric    schedule 23.05.2012
comment
Значит, в этом случае JSON не может хранить undefined? - person Derek 朕會功夫; 24.05.2012
comment
@ Дерек: Верно. Я думаю, JSON.stringify преобразует его в null - person Eric; 24.05.2012
comment
@Derek: JSON.stringify исключает элементы со значениями undefined. Переменная, установленная на undefined, неотличима от переменной, которая никогда не была установлена. - person apsillers; 24.05.2012
comment
@apsillers: ... по крайней мере, с точки зрения JSON. Установка для свойства значения undefined создаст свойство. - person Bergi; 24.05.2012
comment
Function.prototype.toJSON Хороший! - person Derek 朕會功夫; 24.05.2012
comment
@Berji: Да, извините, это важный отказ. На уровне JSON они неотличимы; на уровне языка это не так. - person apsillers; 24.05.2012
comment
Что касается почему Function.prototype.toJSON, это хорошо объясняет. - person Reality; 23.05.2021

Вот еще один способ использования .prototype. Вы можете добавить функцию для строкового преобразования

JSON.stringify(obj, function(k, v) {
  if (typeof v === 'function') {
    return v + '';
  }
  return v;
});
person Zim    schedule 24.03.2013

Не предполагается, что методы (или любые функции) привязываются к строкам - тем более, что большинство методов встроенных объектов (и, следовательно, прототипов любых определяемых пользователем объектов) представляют собой собственный код.

Если вам действительно он нужен для вывода ваших методов, вы можете переопределить метод .toString вашего объекта, но когда вы вызываете JSON.parse для строкового вывода, он будет обрабатывать метод так, как если бы он был просто строка, и чтобы иметь возможность вызывать ее как функцию, вам придется eval ее - практика, которая обычно не рекомендуется.

person JKing    schedule 23.05.2012