Stackoverflow error on Javascript toJSON custom method
脚本
在阅读了这个答案之后,我意识到我可以从JSON文本开始创建对象。
所以我猜我可以用这个有用的JSON方法做相反的事情:
所以我这样做了:
1 2 3 4 5 6 7 8 9 10 11 | function MyObject(id, value, desc) { this.id = id; this.value = value; this.desc = desc; this.toJSON = function() { return JSON.stringify(this); } } |
但是当我运行这个东西(演示)时,会发生一个
在谷歌搜索了一下之后,我发现了两个解释这种行为的参考资料:
- mdn上的json.stringify()方法。
- json.org上的javascript文章中的json
如果我说对了,
问题
认为这是因为
解决方法可以是:(不确定此代码的可靠性)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var obj = { value: 1, name:"John", toJSON: function() { var ret, fn = this.toJSON; delete this.toJSON; ret = JSON.stringify(this); this.toJSON = fn; return ret; } } |
用途:
1 2 3 | obj.toJSON(); //"{"value":1,"name":"John"}" obj.lastName ="Smith"; obj.toJSON(); //"{"value":1,"name":"John","lastName":"Smith"}" |
也许使用Clousure更漂亮一点:(然后我想我可以说它是安全的)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | var obj = { value: 1, name:"John", toJSON: (function() { function fn() { var ret; delete this.toJSON; ret = JSON.stringify(this); this.toJSON = fn; return ret; } return fn; })() } |
因此,在阅读了@filmor的评论后,我想到了另一种处理方法。不是很漂亮,但很管用。
使用function.caller我可以检测是否使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var obj = { value: 1, name:"John", toJSON: (function() { return function fn() { var ret; delete this.toJSON; ret = JSON.stringify(this); if ( fn.caller === JSON.stringify ) { ret = JSON.parse( ret ); } this.toJSON = fn; return ret; } })() } |
问题1,
我不确定它是否保留,但例如,本机日期对象使用tojson创建一个字符串化的日期表示:
1 2 | (new Date()).toJSON(); // ->"2012-10-20T01:58:21.427Z" JSON.stringify({d: new Date()}); // -> {"d":"2012-10-20T01:58:21.427Z"}" |
问题2,一个简单的解决方案:
创建忽略tojson方法的自定义stringify函数(您可以将其添加到已经存在的全局
1 2 3 4 5 6 7 8 | JSON.customStringify = function (obj) { var fn = obj.toJSON; obj.toJSON = undefined; var json = JSON.stringify(obj); obj.toJSON = fn; return json; } |
现在很容易在所有对象中使用:
1 2 3 4 5 6 7 8 9 10 | function MyObject(id, value, desc) { this.id = id; this.value = value; this.desc = desc; this.toJSON = function() { return JSON.customStringify(this); } } |
为了使其更简单,另外添加:
1 2 3 4 | JSON.customStringifyMethod = function () { return JSON.customStringify(this); } |
现在,您的对象可能看起来像:
1 2 3 4 5 6 7 | function MyObject(id, value, desc) { this.id = id; this.value = value; this.desc = desc; this.toJSON = JSON.customStringifyMethod; } |