有没有一种方法可以指定在序列化对象时将对象的哪些数据传递给序列化器? [英] Is there a way of specifying what data of an object is passed to the serializer when it's being serialized?

查看:155
本文介绍了有没有一种方法可以指定在序列化对象时将对象的哪些数据传递给序列化器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用本机chrome的JSON.stringify序列化非常复杂的数据结构(稍后将切换到某些序列化库以支持跨浏览器).大部分数据可以看作是静态数据,而有些则是动态数据.

I'm serializing quite complex data-structures using native JSON.stringify of chrome(will switch to some serialization library later for cross-browser support). Most of the data can be looked upon as static, but some is dynamic.

构造数据时,我希望能够做类似的事情

When constructing the data I'd like to be able to do something like

var dynamicString=new String();
{a:"foo", b:dynamicString}

然后稍后设置dynamicString的原始字符串值.我想这样做而不是更改该对象的属性"b",因为这样可以更轻松地构造此数据. IE.像这样:

Then set the primitive string-value of dynamicString later on. I'd like to do this rather than changing the property "b" of that object because this would allow for constructing this data a lot easier. I.e. something like:

我已经发现不能更改String对象的原始值.我还发现可以将valueOf-function设置为自定义函数,并且通过在该函数中返回所需的值,基本上可以通过执行以下操作来实现:

I've already found out the primitive value of a String-object can't be changed. I've also found out that the valueOf-function can be set to a custom function, and by returning the desired value in that function this can basically be achieved if doing things like:

var dynamicString=new String("bar");
a.valueOf=function(){return ("foo")};
alert (a+"bar");//foobar

问题在于,序列化显然没有使用valueOf-function.在这种情况下,对dynamicString-object进行序列化会将"bar"放入JSON.stringify返回的字符串中,而不是所需的"foo"中.

The problem is that the serialization apparently doesn't use the valueOf-function. Serializing the dynamicString-object in this case puts "bar" in the string returned by JSON.stringify, rather than "foo" which is desired.

一种获取我想要的方法的方法是在序列化之前递归循环遍历数据结构的所有对象,并用它们返回的原始值替换dynamicData-objects.但我想避免这种情况.

One way of getting what I'm after is recursively looping though all the objects of the data-structure prior to serialization, and replacing dynamicData-objects by the primitive value they return. But I'd like to avoid that if possible.

有什么建议吗?

我当然也可以在数据中放置一个对象,我也可以参考该对象.然后,我可以动态"设置该对象的数据,这将反映在结果字符串中.但这在结构上增加了另一个层次.我只想要一个字符串,而不是一个具有字符串属性的对象.

I could of course also put an object in the data, which I also have a reference to. Then I can set the data of that object "dynamically", which will be reflected in the result-string. But that adds another level in the structure. I just want a string, not an object with a string-property.

推荐答案

我还发现可以将valueOf-function设置为自定义函数,并且通过在该函数中返回所需的值,基本上可以通过执行以下操作来实现:

I've also found out that the valueOf-function can be set to a custom function, and by returning the desired value in that function this can basically be achieved if doing things like:

var a = new String("bar");
a.valueOf = function(){return ("foo")};
console.log(a+"bar"); // "foobar"

但是,如果覆盖valueOf,则使用String对象(内部值有所不同)没有任何意义.将普通对象与valueOf函数一起使用,或者仅将其与动态更改的属性一起使用.使用当前的方法,您将得到

Yet, if you overwrite valueOf it does not make any sense to use a String object (with some different internal value). Use a plain object with a valueOf function, or even with just a property which is changed dynamically. With your current approach, you're getting

console.log(a.concat("bar")); // "barbar"!

问题在于,序列化显然没有使用valueOf-function.在这种情况下,对dynamicString-object进行序列化会将"bar"放入JSON.stringify返回的字符串中,而不是所需的"foo"中.

The problem is that the serialization apparently doesn't use the valueOf-function. Serializing the dynamicString-object in this case puts "bar" in the string returned by JSON.stringify, rather than "foo" which is desired.

是的. JSON.stringify确实对对象调用了toJSON方法,在您的情况下,该方法仍返回内部值.如果您覆盖它,它将起作用:

Yes. JSON.stringify does call the toJSON method on objects, which in your case still returns the internal value. If you overwrite that, it will work:

a.toJSON = a.valueOf;
console.log(JSON.stringify(a)); // '"foo"'


如上所述,使用本机String对象没有多大意义.相反,我们应该为它们创建一个额外的构造函数:


As said above, using native String objects doesn't make much sense. Instead, we should create an extra constructor for them:

function DynamicString(value) {
    if (!(this instanceof DynamicString))
        return new DynamicString(value);   
    this.set(value);
}
var p = DynamicString.prototype = Object.create(String.prototype, {
    constructor: {value: DynamicString, configurable: true}
});
p.set = function(value) {
    this.__value__ = String(value);
};
p.valueOf = p.toString = p.toJSON = function() {
    return this.__value__;
};

现在,使用它:

var a = new DynamicString("foo");
console.log(a+"bar"); // "foobar"
console.log(JSON.stringify({a:a, b:"bar"})); // '{"a":"foo","b":"bar"}'

您甚至还可以使用所有的String.prototype方法(但是它们会生成原始字符串,而不是动态字符串).

You even got all the String.prototype methods on it (yet they will yield primitive strings, not dynamic ones).

这篇关于有没有一种方法可以指定在序列化对象时将对象的哪些数据传递给序列化器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆