Как вы используете JSON.stringify в пользовательском методе toJSON? - PullRequest
22 голосов
/ 27 ноября 2010

Итак, JSON.stringify предоставляет отличный способ превратить объект JS, например:

var baz = {"foo":1, "bar":someFunction};

в строку JSON, например:

{"foo":1}

Это делается с помощью необязательного второго аргумента, который определяет, какие поля должны быть сериализованы:

JSON.stringify(baz, ["foo"]);

Отлично, но есть проблема. Допустим, ваш baz фактически является свойством другого объекта, и вы хотите сериализовать этот другой объект:

someObject.baz = {"foo":1, "bar":someFunction};
JSON.stringify(someObject, ["baz"]);

Ну, обычно вы просто определяете метод toJSON для baz, например ::

someObject.baz = {"foo":1, "bar":someFunction};
someObject.baz.toJSON = function() { /* logic to "toJSON" baz*/ }
JSON.stringify(someObject, ["baz"]);

Теперь, как я упоминал ранее, у нас уже есть идеальная логика для "toJSON" baz:

someObject.baz.toJSON = function() {
    return JSON.stringify(baz, ["foo"]);
}

но если вы попытаетесь вставить это в ваш toJSON, вы получите ошибку рекурсии, потому что stringify вызовет toJSON, который запустит stringify, что будет ...: - (

Вы можете обойти это с помощью хака:

someObject.baz.toJSON = function() {
    var oldToJON = this.toJSON;
    this.toJSON = null;
    var ret = JSON.stringify(baz, ["foo"]);
    this.toJSON = oldToJON;
    return ret;
}

Но ... это кажется неправильным. Итак, мой вопрос: есть ли способ использовать изящную встроенную мощь сериализации JSON.stringify внутри метода toJSON объекта (без необходимости скрывать сам метод toJSON во время операции stringify )

1 Ответ

39 голосов
/ 27 ноября 2010

json2.js Крокфорда говорит:

Метод toJSON не сериализуется: он возвращает значение, представленное парой имя / значение, которое должно быть сериализовано, или не определено, если ничего не нужно сериализовать.

Таким образом, вы просто должны вернуть значение, которое вы хотите сериализовать. В вашем случае baz.toJSON должен просто возвращать часть объекта baz, которую вы хотите сериализовать:

someObject.baz.toJSON = function() {
  return { foo: this.foo };
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...