我正在寻找一种解决方案,将Javascript对象序列化(和反序列化)到跨浏览器的字符串,包括碰巧是函数的对象的成员。典型的对象如下所示:
{
color: 'red',
doSomething: function (arg) {
alert('Do someting called with ' + arg);
}
}
doSomething()只包含局部变量(不需要序列化调用上下文!)。
JSON.stringify()将忽略'doSomething'成员,因为它是一个函数。我知道toSource()方法会做我想要的,但它是特定于FF的。
答案 0 :(得分:8)
您可以将JSON.stringify
与replacer
类似使用:
JSON.stringify({
color: 'red',
doSomething: function (arg) {
alert('Do someting called with ' + arg);
}
}, function(key, val) {
return (typeof val === 'function') ? '' + val : val;
});
答案 1 :(得分:6)
快速而肮脏的方式是这样的:
Object.prototype.toJSON = function() {
var sobj = {}, i;
for (i in this)
if (this.hasOwnProperty(i))
sobj[i] = typeof this[i] == 'function' ?
this[i].toString() : this[i];
return sobj;
};
显然这会影响代码中每个对象的序列化,并且可能会使用未经过滤的for in
循环来绊倒niave代码。 “正确”的方法是编写一个递归函数,在任何给定对象的所有后代成员上添加toJSON
函数,处理循环引用等。但是,假设单线程Javascript(没有Web Workers),此方法应该可以工作,不会产生任何意外的副作用。
必须在Array的原型中添加类似的函数,以通过返回数组而不是对象来覆盖Object。另一个选择是附加一个单独的选项,让它根据对象自身的性质选择性地返回一个数组或一个对象,但它可能会更慢。
function JSONstringifyWithFuncs(obj) {
Object.prototype.toJSON = function() {
var sobj = {}, i;
for (i in this)
if (this.hasOwnProperty(i))
sobj[i] = typeof this[i] == 'function' ?
this[i].toString() : this[i];
return sobj;
};
Array.prototype.toJSON = function() {
var sarr = [], i;
for (i = 0 ; i < this.length; i++)
sarr.push(typeof this[i] == 'function' ? this[i].toString() : this[i]);
return sarr;
};
var str = JSON.stringify(obj);
delete Object.prototype.toJSON;
delete Array.prototype.toJSON;
return str;
}
答案 2 :(得分:1)
像这样......
(function(o) {
var s = "";
for (var x in o) {
s += x + ": " + o[x] + "\n";
}
return s;
})(obj)
注意:这是一个表达式。它返回作为参数传入的对象的字符串表示形式(在我的示例中,我将传入名为obj的变量)。
您还可以覆盖Object原型的toString方法:
Object.prototype.toString = function() {
// define what string you want to return when toString is called on objects
}
答案 3 :(得分:1)
没有物体本身的帮助是不可能的。例如,您如何序列化此表达式的结果?
(function () { var x; return { get: function () { return x; }, set: function (y) { return x = y; } }; })();
如果您只是获取函数的文本,那么当您反序列化时,x
将引用全局变量,而不是闭包中的变量。此外,如果您的函数关闭浏览器状态(比如对div的引用),您必须考虑您想要的含义。
当然,您可以编写自己的特定于各个对象的方法,这些方法编码您希望引用其他对象的语义。
答案 4 :(得分:1)