Javascript:字符串化对象(包括函数类型的成员)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3685703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Javascript: stringify object (including members of type function)
提问by Yannick Deltroo
I'm looking for a solution to serialize (and unserialize) Javascript objects to a string across browsers, including members of the object that happen to be functions. A typical object will look like this:
我正在寻找一种解决方案,可以跨浏览器将 Javascript 对象序列化(和反序列化)为字符串,包括恰好是函数的对象成员。一个典型的对象看起来像这样:
{
color: 'red',
doSomething: function (arg) {
alert('Do someting called with ' + arg);
}
}
doSomething() will only contain local variables (no need to also serialize the calling context!).
doSomething() 将只包含局部变量(不需要也序列化调用上下文!)。
JSON.stringify() will ignore the 'doSomething' member because it's a function. I known the toSource() method will do what I want but it's FF specific.
JSON.stringify() 将忽略 'doSomething' 成员,因为它是一个函数。我知道 toSource() 方法会做我想做的事,但它是特定于 FF 的。
回答by CD..
You can use JSON.stringifywith a replacerlike:
你可以使用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;
});
回答by MooGoo
A quick and dirty way would be like this:
一种快速而肮脏的方式是这样的:
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;
};
Obviously this will affect the serialization of every object in your code, and could trip up niave code using unfiltered for inloops. The "proper" way would be to write a recursive function that would add the toJSONfunction on all the descendent members of any given object, dealing with circular references and such. However, assuming single threaded Javascript (no Web Workers), this method should work and not produce any unintended side effects.
显然,这会影响代码中每个对象的序列化,并且可能会使用未过滤的for in循环跳出 niave 代码。“正确”的方法是编写一个递归函数,该toJSON函数将在任何给定对象的所有后代成员上添加该函数,处理循环引用等。但是,假设单线程 Javascript(没有 Web Workers),这个方法应该可以工作并且不会产生任何意外的副作用。
A similar function must be added to Array's prototype to override Object's by returning an array and not an object. Another option would be attaching a single one and let it selectively return an array or an object depending on the objects' own nature but it would probably be slower.
必须将类似的函数添加到 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;
}
回答by ?ime Vidas
Something like this...
像这样的东西...
(function(o) {
var s = "";
for (var x in o) {
s += x + ": " + o[x] + "\n";
}
return s;
})(obj)
Note: this is an expression. It returns a string representation of the object that is passed in as an argument (in my example, I'm passing the in an variable named obj).
注意:这是一个表达式。它返回作为参数传入的对象的字符串表示(在我的示例中,我将传入名为 obj 的变量)。
You can also override the toString method of the Object's prototype:
您还可以覆盖对象原型的 toString 方法:
Object.prototype.toString = function() {
// define what string you want to return when toString is called on objects
}
回答by Mike Stay
It's impossible without the help of the object itself. For example, how would you serialize the result of this expression?
没有对象本身的帮助,这是不可能的。例如,您将如何序列化此表达式的结果?
(function () {
var x;
return {
get: function () { return x; },
set: function (y) { return x = y; }
};
})();
If you just take the text of the function, then when you deserialize, xwill refer to the global variable, not one in a closure. Also, if your function closes over browser state (like a reference to a div), you'd have to think about what you want that to mean.
如果只取函数的文本,那么在反序列化时,x将引用全局变量,而不是闭包中的一个。此外,如果您的函数在浏览器状态下关闭(如对 div 的引用),则您必须考虑您想要的意思。
You can, of course, write your own methods specific to individual objects that encode what semantics you want references to other objects to have.
当然,您可以编写自己的特定于单个对象的方法,这些方法对您希望引用其他对象的语义进行编码。
回答by vadimk
JSONfn plugin is exactly what you're looking for.
JSONfn 插件正是您正在寻找的。
http://www.eslinstructor.net/jsonfn/
http://www.eslinstructor.net/jsonfn/
--Vadim
--瓦迪姆

