方案
阅读this answer后,我意识到我可以从JSON文字开始创建对象。
所以我猜我只能使用这个有用的JSON方法做相反的事情:
JSON.stringify(myObject)
。
所以我做了如下:
function MyObject(id, value, desc)
{
this.id = id;
this.value = value;
this.desc = desc;
this.toJSON = function()
{
return JSON.stringify(this);
}
}
但是当我运行这些东西(demo)时会发生Maximum call stack size exceeded
错误。
在谷歌搜索后,我找到了两个解释这种行为的引用:
如果我做对了,.toJSON
会覆盖.stringify
。因此,如果第一个调用第二个,则会生成一个循环。
问题
toJSON
是一种保留的特殊关键字?.toJSON
名称更改为.display
。不那么优雅。还有另一种解决方案吗?答案 0 :(得分:6)
认为这是因为toJSON
是半保留的:stringify
将检查对象并查看它是否有一个名为toJSON
的方法,然后尝试调用它来对结果进行字符串化。
解决方法可以是:(不确定此代码的可靠性)
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;
}
}
用法:
obj.toJSON(); // "{\"value\":1,\"name\":\"John\"}"
obj.lastName = "Smith";
obj.toJSON(); // "{\"value\":1,\"name\":\"John\",\"lastName\":\"Smith\"}"
也许使用clousure有点漂亮:(然后我想我可以说它是安全的)
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我可以使用fn
JSON.stringify
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 :(得分:3)
问题1,toJSON
保留了吗?
我不确定它是否保留,但是例如本机Date对象使用toJSON来创建字符串化日期表示:
(new Date()).toJSON(); // -> "2012-10-20T01:58:21.427Z"
JSON.stringify({d: new Date()}); // -> {"d":"2012-10-20T01:58:21.427Z"}"
问题2,一个简单的解决方案:
创建自定义stringify函数,忽略toJSON方法(您可以将其添加到已存在的全局JSON
):
JSON.customStringify = function (obj) {
var fn = obj.toJSON;
obj.toJSON = undefined;
var json = JSON.stringify(obj);
obj.toJSON = fn;
return json;
}
现在在所有对象中使用非常简单:
function MyObject(id, value, desc)
{
this.id = id;
this.value = value;
this.desc = desc;
this.toJSON = function()
{
return JSON.customStringify(this);
}
}
为了使其更容易添加:
JSON.customStringifyMethod = function () {
return JSON.customStringify(this);
}
现在您的对象可能如下所示:
function MyObject(id, value, desc)
{
this.id = id;
this.value = value;
this.desc = desc;
this.toJSON = JSON.customStringifyMethod;
}