java 对象中有很多引用,甚至会出现循环引用,比如 user 对象中有 school 对象,school 对象中又有 user 对象,这样在对 user 对象序列化的时候,就会出现死循环,导致内存溢出。通过一定的方式,将每个对象增加ID 和 REF 引用标识最终可以解决这个问题,生成类似下面的样式:
这样就相当于给 user 对象增加一个 $id 标识,且值为 3,在school 中引用 user 对象的时候,只需要增加一个 $ref 值为 3的引用即可。 但是,序列化的字符串传递给前台后,生成的 JSON对象中还需要再替换回来,所以就有了 json 对象的引用替换。
将对象中的所有 $id 的对象取出放到容器中,然后将对象中所有包含 $ref 属性的对象,根据值替换为容器中的对象。(这里不考虑对象本身含有 $id 和 $ref 名称的属性)
代码:
<script type="text/javascript">
var t = '{"name":"lixun","user":{"name":"xx","school":{"name":"sss","user":{"$ref":"3"}},"$id":"3"}}';
var tt = '';
var target = eval('('+t+')');
console.log(target);
var fixObject = function(target){
var map = {};
var scan = function(o){
if(o.hasOwnProperty('$id')){
var v = o['$id'];
map[v] = o;
// console.log(o.prototype.constructor);
}
//如果含有ID ,则为独立对象,需要对ref进行替换
if(!$.isEmptyObject(o) && !$.isFunction(o) ){
for(var n in o){
if(o.hasOwnProperty(n)){
if(o[n] instanceof Object){
scan(o[n]);
}
}
}
}
};
var replaceObj = function(o){
if(o.hasOwnProperty('$ref')){
var v = o['$ref'];
o = map[v];
return o;//关键点
}
if(!$.isEmptyObject(o) && !$.isFunction(o)){
for(var n in o){
if(o[n] instanceof Object){
o[n] = replaceObj(o[n]);//关键点
}
}
}
return o;
};
scan(target);
console.log(map);
replaceObj(target);
};
fixObject(target);
console.log(target);
</script>
效果图:
这样就可以出现循环引用的效果了,而且所有的 $ref 属性的对象都可以查找到原本的值了。
转载请注明出处: https://chrunlee.cn/article/json-parse-convert-replace.html