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

mac*_*ost 23 javascript json

所以,JSON.stringify提供了一个转换JS对象的好方法:

var baz = {"foo":1, "bar":someFunction};
Run Code Online (Sandbox Code Playgroud)

进入JSON字符串,如:

{"foo":1}
Run Code Online (Sandbox Code Playgroud)

它使用可选的第二个参数来控制应该序列化哪些字段:

JSON.stringify(baz, ["foo"]);
Run Code Online (Sandbox Code Playgroud)

那很好,但是有一个问题.假设您的"baz"实际上是另一个对象的属性,并且您想序列化该另一个对象:

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

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

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

现在,正如我之前提到的,我们已经有了"toJSON"baz的完美逻辑:

someObject.baz.toJSON = function() {
    return JSON.stringify(baz, ["foo"]);
}
Run Code Online (Sandbox Code Playgroud)

但是如果你尝试把它放到你的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;
}
Run Code Online (Sandbox Code Playgroud)

但是......这似乎是错的.所以,我的问题是:是否有可以利用任何方式漂亮的内置JSON.stringify的系列化电源内部对象的方法的toJSON(不必隐藏在字符串化操作过程中的toJSON方法本身)?

cas*_*nca 41

Crockford的json2.js说:

甲的toJSON方法不序列:它返回由该名称/值对应被序列化,或未定义如果没有应序列所表示的值.

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

someObject.baz.toJSON = function() {
  return { foo: this.foo };
};
Run Code Online (Sandbox Code Playgroud)