本文介绍JavaScript中实现JSON深度合并的方法。针对浅层合并导致嵌套对象整体被覆盖的问题,通过递归遍历子属性,保留未冲突的原有属性,实现深层配置的完美合并。
JavaScript实现JSON深度递归合并示例
本文通过具体示例,详细讲解如何利用JavaScript完成JSON数据的合并操作。内容旨在为开发者提供实用的参考方案。
为何需要编写这段代码
在实际开发场景中,我们常需集成各类自主开发或第三方的工具。部分工具的配置文件极为细致,若使用频率较低尚可接受,但高频使用时极易引发代码冗余。为此,通常会对这些工具进行二次封装,将不常变动的配置设为默认值;若需调整,只需传入新配置以覆盖原有配置即可。
起初我认为这是一个简单的需求
var json1 = { // 固定的配置
a: 1,
b: 2,
c: 3,
}
var json2 = { // 作为参数传入的配置
a: 11,
d: 14,
}
json3 = { // 合并后的结果
a: 11,
b: 2,
c: 3,
d: 14,
}
如前所述,看似简单。然而,当配置涉及多层嵌套时,常规的$.extend或for in赋值方式便无法有效解决问题。
var json1 = {
a: 1,
b: {
b1: 'hello',
b2: 'world',
},
}
var json2 = {
b: { b2: 'china' },
c: 3,
}
json3 = { // 合并后的结果
a: 1,
b: { b2: 'chila' },
c: 3,
}
从结果可见,我们的初衷是希望json2中的b.b2: 'china'能替换json1中的b.b2: 'world',但常规操作仅会整体替换整个object/json,而不会遍历其内部属性,从而导致b.b1属性丢失。
因此,实现了以下代码:
// 遇到相同元素级属性,以后者(main)为准
// 不返还新Object,而是main改变
function mergeJSON (minor, main) {
for (var key in minor) {
if (main[key] === undefined) { // 不冲突的,直接赋值
main[key] = minor[key];
continue;
}
// 冲突了,如果是Object,看看有么有不冲突的属性
// 不是Object 则以main为主,忽略即可。故不需要else
if (isJSON(minor[key])) {
// arguments.callee 递归调用,并且与函数名解耦
arguments.callee(minor[key], main[key]);
}
}
}
// 附上工具
function isJSON(target) {
return typeof target == "object" && target.constructor == Object;
}
尽管代码仅十余行,但实用性显著。经粗略搜索,尚未发现更优的解决方案。其中简单的递归思想结合arguments.callee的使用,颇具探讨价值。
PS:此处推荐几款相关的JSON在线工具供参考:
在线JSON代码检验、校验、美化、格式化工具: http://tools.jb51.net/code/json
JSON在线格式化工具: http://tools.jb51.net/code/jsonformat
在线XML/JSON互相转换工具: http://tools.jb51.net/code/xmljson
json代码在线格式化/美化/压缩/编辑/转换工具: http://tools.jb51.net/code/jsoncodeformat
在线json压缩/转义工具: http://tools.jb51.net/code/json_yasuo_trans
更多关于JavaScript相关内容可查看本站专题:《JavaScript中json操作技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。