如何在自定义toJSON方法中使用JSON.stringify?

时间:2010-11-26 23:48:18

标签: javascript json

因此,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"]);

好吧,通常你只需要在baz上定义一个toJSON方法,例如:

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方法的漂亮的内置序列化功能(在stringify期间不必隐藏toJSON方法本身)操作)?

1 个答案:

答案 0 :(得分:38)

Crockford's json2.js说:

  

toJSON方法没有序列化:它返回应该序列化的名称/值对表示的值,如果没有任何序列化,则返回undefined。

因此,您只需返回要序列化的值。在您的情况下,baz.toJSON应该只返回您要序列化的baz对象部分:

someObject.baz.toJSON = function() {
  return { foo: this.foo };
};