Fastjson在遇到循环引用时,会在JSON中出现$ref
,下面的工具函数会把$ref
引用恢复为对象。
用法:
// 转换带引用的对象
var jsonObj = JSON.parse(jsonStr);
jsonUtils.parse(jsonObj);
// 直接转换JSON
var jsonObj = jsonUtils.parse(jsonStr);
工具函数:
var jsonUtils = (function(){
var parse = function(json) {
if (typeof json == "string") {
json = JSON.parse(json);
}
_parse(json, null, null, [], json);
return json;
}
var _parse = function(json, index, last, stack, root) {
if (isObejct(json)) {
var ref = json.$ref;
if (ref) {
var replaceNode = _find(ref, stack, root);
last[index] = replaceNode;
return;
}
for(var item in json) {
stack.push(json);
_parse(json[item], item, json, stack, root);
stack.pop();
}
} else if (isArray(json)) {
for(let i=0; i<json.length; i++) {
stack.push(json);
_parse(json[i], i, json, stack, root);
stack.pop();
}
}
}
var _find = function(ref, stack, root) {
if (ref == "@") {
return stack[stack.length-1];
} else if (ref == "$") {
return root;
} else if (ref == "..") {
return stack[stack.length-2];
} else if (ref == "../..") {
return stack[stack.length-3];
} else {
var refPath = ref.split(/[\.\[\]]/);
var target;
for (var refItem of refPath) {
if (refItem == "$") {
target = root;
continue;
}
if (refItem == "") {
continue;
}
target = target[refItem];
}
return target;
}
}
var isArray = function(json) {
return Array.isArray(json);
}
var isObejct = function(json) {
return "object" == typeof json && !isArray(json);
}
return {
parse: parse,
isArray: isArray,
isObejct: isObejct
};
})();