Javascript:字符串化对象(包括类型函数的成员)
Posted
技术标签:
【中文标题】Javascript:字符串化对象(包括类型函数的成员)【英文标题】:Javascript: stringify object (including members of type function) 【发布时间】:2011-04-10 18:51:33 【问题描述】:我正在寻找一种跨浏览器将 javascript 对象序列化(和反序列化)为字符串的解决方案,包括恰好是函数的对象成员。一个典型的对象如下所示:
color: 'red',
doSomething: function (arg)
alert('Do someting called with ' + arg);
doSomething() 将只包含局部变量(无需同时序列化调用上下文!)。
JSON.stringify() 将忽略 'doSomething' 成员,因为它是一个函数。我知道 toSource() 方法会做我想做的,但它是 FF 特定的。
【问题讨论】:
我只是发表评论,因为我没有提供完整的解决方案。可能有帮助的一件事是,您可以通过调用toString()
来对函数进行字符串化。 jsfiddle.net/HFMaz 不确定是否支持跨浏览器。
这是经常被问到的,但我找不到任何相关的东西:\为什么你仍然需要序列化函数?也许有更好的方法来安排你的代码?
这是所见即所得的项目。每个 Javascript 对象(带有方法)都定义了页面组件的行为。页面内容(包括 JS 行为)必须保存在服务器端,因此需要序列化。
代码是如何创建的?看来您应该可以在流程的早期阶段访问所有这些的字符串表示形式。
我希望这不会被广大公众使用......否则你必须确保我无法 XSS 那个东西。
【参考方案1】:
您可以将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;
);
【讨论】:
我最终使用了JSON.stringify(myObject, function(key, val) return (typeof val === 'function') ? '[function]' : val; , 4);
,它的输出非常好。【参考方案2】:
一种快速而肮脏的方式是这样的:
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
循环使 naive 代码绊倒。 “正确”的方法是编写一个递归函数,在任何给定对象的所有后代成员上添加 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;
http://jsbin.com/yerumateno/2/edit
【讨论】:
很好,除了数组不再序列化为数组。 解析函数会是什么样子?所有函数都在字符串中,所以在解析时我们需要将它们转换回函数。【参考方案3】:这样的……
(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
【讨论】:
【参考方案4】:没有对象本身的帮助是不可能的。例如,你将如何序列化这个表达式的结果?
(功能 () 变量 x; 返回 获取:函数()返回x; , 设置:函数(y)返回x = y; ; )();如果你只取函数的文本,那么当你反序列化时,x
将引用全局变量,而不是闭包中的一个。此外,如果您的函数在浏览器状态下关闭(例如对 div 的引用),您必须考虑您想要它的含义。
当然,您可以编写自己的特定于单个对象的方法,这些方法对您希望引用其他对象具有的语义进行编码。
【讨论】:
【参考方案5】:JSONfn 插件正是您正在寻找的。p>
http://www.eslinstructor.net/jsonfn/
--瓦迪姆
【讨论】:
我已经用我的对象进行了测试,该对象具有功能但无法正常工作。以上是关于Javascript:字符串化对象(包括类型函数的成员)的主要内容,如果未能解决你的问题,请参考以下文章