JavaScript实现JSON合并操作示例【递归深度合并】


Posted in Javascript onSeptember 07, 2018

本文实例讲述了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,
}

如上述,确实很简单。可事实是,当配置不再是仅仅一层嵌套时,常用的合并如$.extendfor 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;
}

虽然只有十几行的代码,但还是挺实用。粗略的挖掘了一下搜索引擎,好像并没有更合适解决问题的代码。简单的递归思想和argument.callee琢磨一下也是有些味道的

Javascript 相关文章推荐
JavaScript 中的replace方法说明
Apr 13 Javascript
jQuery 网易相册鼠标移动显示隐藏效果实现代码
Mar 31 Javascript
JavaScript中使用Substring删除字符串最后一个字符
Nov 03 Javascript
JavaScript操作Cookie详解
Feb 28 Javascript
基于JS2Image实现圣诞树代码
Dec 24 Javascript
javascript自动切换焦点控制效果完整实例
Feb 02 Javascript
jQuery的框架介绍
May 11 Javascript
AngularJS中$injector、$rootScope和$scope的概念和关联关系深入分析
Jan 19 Javascript
微信小程序实现页面跳转传值的方法
Oct 12 Javascript
Vue CLI3.0中使用jQuery和Bootstrap的方法
Feb 28 jQuery
JointJS JavaScript流程图绘制框架解析
Aug 15 Javascript
jQuery三组基本动画与自定义动画操作实例总结
May 09 jQuery
Bootstrap-table使用footerFormatter做统计列功能
Sep 07 #Javascript
jQuery实现为动态添加的元素绑定事件实例分析
Sep 07 #jQuery
Bootstrap-table自定义可编辑每页显示记录数
Sep 07 #Javascript
vue.js 双层嵌套for遍历的方法详解, 类似php foreach()
Sep 07 #Javascript
jQuery插件实现的日历功能示例【附源码下载】
Sep 07 #jQuery
vue利用v-for嵌套输出多层对象,分别输出到个表的方法
Sep 07 #Javascript
Vue中使用sass实现换肤功能
Sep 07 #Javascript
You might like
Yii获取当前url和域名的方法
2015/06/08 PHP
CI框架支持$_GET的两种实现方法
2016/05/18 PHP
PHP+mysql实现从数据库获取下拉树功能示例
2017/01/06 PHP
PHP PDO数据库操作预处理与注意事项
2019/03/16 PHP
一个简单的javascript类定义例子
2009/09/12 Javascript
jQuery $.data()方法使用注意细节
2012/12/31 Javascript
js监听鼠标点击和键盘点击事件并自动跳转页面
2014/09/24 Javascript
javascript实现控制的多级下拉菜单
2015/07/05 Javascript
json对象转为字符串,当做参数传递时加密解密的实现方法
2016/06/29 Javascript
JQueryEasyUI之DataGrid数据显示
2016/11/23 Javascript
Javascript中字符串和数字的操作方法整理
2017/01/22 Javascript
jQuery Layer弹出层传值到父页面的实现代码
2017/08/17 jQuery
JavaScript字符和ASCII实现互相转换
2020/06/03 Javascript
vue 监听窗口变化对页面部分元素重新渲染操作
2020/07/28 Javascript
[12:29]《一刀刀一天》之DOTA全时刻19:蝙蝠骑士田伯光再度不举
2014/06/10 DOTA
[01:33:30]DOTA2-DPC中国联赛 正赛 RNG vs Phoenix BO3 第二场 2月5日
2021/03/11 DOTA
Python中的深拷贝和浅拷贝详解
2015/06/03 Python
Python实现新浪博客备份的方法
2016/04/27 Python
使用Django Form解决表单数据无法动态刷新的两种方法
2017/07/14 Python
Python之自动获取公网IP的实例讲解
2017/10/01 Python
Python set常用操作函数集锦
2017/11/15 Python
对python中的logger模块全面讲解
2018/04/28 Python
详解pyenv下使用python matplotlib模块的问题解决
2018/11/29 Python
python3转换code128条形码的方法
2019/04/17 Python
如何用Matlab和Python读取Netcdf文件
2021/02/19 Python
HTML5移动开发图片压缩上传功能
2016/11/09 HTML / CSS
移动端html5判断是否滚动到底部并且下拉加载
2019/11/19 HTML / CSS
香蕉共和国加拿大官网:Banana Republic加拿大
2018/08/06 全球购物
汇科协同Java笔试题
2012/03/31 面试题
医院护士求职自荐信格式
2013/09/21 职场文书
英语专业应届生求职信范文
2013/11/15 职场文书
彩色的翅膀教学反思
2014/04/25 职场文书
促销活动总结范文
2014/04/30 职场文书
无毒社区工作方案
2014/05/23 职场文书
女性健康讲座主持词
2015/07/04 职场文书
优秀团员主要事迹范文
2015/11/05 职场文书