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在IE和FireFox中的不同表现简析
Dec 03 Javascript
javascript中自定义对象的属性方法分享
Jul 12 Javascript
JS模拟bootstrap下拉菜单效果实例
Jun 17 Javascript
js实现浏览器倒计时跳转页面效果
Aug 12 Javascript
使用Ajax生成的Excel文件并下载的实例
Nov 21 Javascript
Bootstrap响应式导航由768px变成992px的实现代码
Jun 15 Javascript
vue 使用自定义指令实现表单校验的方法
Aug 28 Javascript
详解ES6 Symbol 的用途
Oct 14 Javascript
vue中的v-if和v-show的区别详解
Sep 01 Javascript
详解vue 自定义组件使用v-model 及探究其中原理
Oct 11 Javascript
javascript异常处理实现原理详解
Feb 17 Javascript
在Chrome DevTools中调试JavaScript的实现
Apr 07 Javascript
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
咖啡的化学
2021/03/03 咖啡文化
PHP运行环境配置与开发环境的配置(图文教程)
2013/06/04 PHP
phpQuery让php处理html代码像jQuery一样方便
2015/01/06 PHP
Laravel 5框架学习之路由、控制器和视图简介
2015/04/07 PHP
thinkPHP+PHPExcel实现读取文件日期的方法(含时分秒)
2016/07/07 PHP
Node.js实战 建立简单的Web服务器
2012/03/08 Javascript
javascript 常用功能总结
2012/03/18 Javascript
jquery图形密码实现方法
2015/03/11 Javascript
深入学习JavaScript中的Rest参数和参数默认值
2015/07/28 Javascript
js限制文本框的输入内容代码分享(3类)
2015/08/20 Javascript
基于jQuery实现动态搜索显示功能
2016/05/05 Javascript
bootstrap网页框架的使用方法
2016/05/10 Javascript
nodejs入门教程一:概念与用法简介
2017/04/24 NodeJs
js使用i18n实现页面国际化的方法
2017/05/09 Javascript
nodejs密码加密中生成随机数的实例代码
2017/07/17 NodeJs
在 Node.js 中使用 async 函数的方法
2017/11/17 Javascript
js断点调试经验分享
2017/12/08 Javascript
基于vue写一个全局Message组件的实现
2019/08/15 Javascript
[06:45]DOTA2卡尔工作室 英雄介绍幻影长矛手篇
2013/07/12 DOTA
[01:03:31]DOTA2上海特级锦标赛B组资格赛#1 Alliance VS Fnatic第二局
2016/02/26 DOTA
[59:53]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第二场 3月6日
2021/03/11 DOTA
python 正则式 概述及常用字符
2009/05/07 Python
Python装饰器的函数式编程详解
2015/02/27 Python
python编写弹球游戏的实现代码
2018/03/12 Python
python框架flask表单实现详解
2019/11/04 Python
Python二次规划和线性规划使用实例
2019/12/09 Python
pandas 对group进行聚合的例子
2019/12/27 Python
python 实现Requests发送带cookies的请求
2021/02/08 Python
使用Filters滤镜弥补CSS3的跨浏览器问题以及兼容低版本IE
2013/01/23 HTML / CSS
大学考试作弊检讨书
2014/01/30 职场文书
大学毕业感言50字
2014/02/07 职场文书
企业宣传工作方案
2014/06/02 职场文书
小学网上祭英烈活动总结
2014/07/05 职场文书
防灾减灾活动总结
2014/08/30 职场文书
MySQL Innodb关键特性之插入缓冲(insert buffer)
2021/04/08 MySQL
关于React Native使用axios进行网络请求的方法
2021/08/02 Javascript