基于对象合并功能的实现示例


Posted in Javascript onOctober 10, 2017

前言

jQuery 中的 $.extend() 是经常使用到工具函数,多用于合并参数(对象),具体用法在这里不过多赘述,可通过传参控制合并过程中是否使用深度拷贝;而ES2015中新增的 Object.assign()方法,也可以实现对象的合并,不过合并过程中使用的是浅拷贝;本文参考了jQuery的extend方法的源码,将自己实现对象合并,即将多个对象的属性复制到目标对象上,若有相同的属性,后面的对象覆盖前面的。

浅拷贝的方式实现对象合并

之前的一篇博文 有专门介绍对象和数组的深浅拷贝,不了解的童鞋请移步。先看实现再解释

function extend() { //extend 浅拷贝实现
  var name,options,copy,
   length = arguments.length,
   i = 1,
   target = arguments[0] || {}; //取目标对象
  
 if(['object','function'].indexOf(typeof target) < 0){
  target = {};
  }
 

  for(;i<length;i++){

  options = arguments[i]

  if(options != null){ //排除空参数的情况 extend({},,)

   for(name in options){ //遍历对象 赋值

   copy = options[name];

   if (copy !== undefined) {
    target[name] = copy;
   }
   }
  }
  }

  return target 
 }

 //测试数据 
 var test1 = {
  a : 1,
  b : {
  c : 2,
  d : 3
  },
  e : [1,'a']
 },
 test2 = {
  b : {
  c : 4,
  d : 5,
  f : 6
  },
  e : [1,'a'],
  g : 7
 }

 var test = extend({},test1,test2);
 console.log(test.b.d); //5

 test2.b.d = 'x'; //修改test2
 console.log(test.b.d); // 'x' test随之修改

思路如下:

1、默认取第一个参数为目标对象,若第一个参数非对象数据类型,则赋值为空对象

2、遍历剩下的参数(源对象),将源对象的属性复制到目标对象上 。

3、返回目标对象为合并的结果

在第二步中没有对源对象的属性值进行判断,所有的全部使用 ‘=' 赋值,所以当源对象的属性值为对象属性时,复制的只是引用值,即为浅拷贝的方式,在测试结果中可以看出 test 和 test2 的 b 属性的属性值,使用的是同一个对象,会互相影响。知道了这些之后,如何实现合并时的深拷贝也应该有思路了。

深度拷贝的方式实现对象合并

需要在复制源对象属性值时,判断值的类型,如果是对象数据类型,则递归调用extend函数。则可以实习深拷贝方式的对象合并,实现如下:

function extend() { //extend 深拷贝实现
  var name,options,src,copy,
   deep = false, //是否深拷贝 默认为false
   length = arguments.length,
   i = 1,
   target = arguments[0] || {};

  //如果第一个参数为boolean类型,赋值给deep
  if(typeof target == 'boolean'){
  deep = arguments[0];
  target = arguments[i] || {}; //目标对象顺延
  i++;
  }

  //如果target不是对象数据类型的话 target赋值为 {}
  if(['object','function'].indexOf(typeof target) < 0){
  target = {};
  }

  for(;i<length;i++){

  options = arguments[i];

  if(options != null){

   for(name in options){

   copy = options[name];
   src = target[name];

   if(target === copy){ //避免重复循环
    continue;
   }

   if(deep && copy && (typeof copy == 'object')){ // 类型判断

    src = Object.prototype.toString.call(copy) == '[object Array]' ? [] : {}; //区分数组和‘对象'
    target[name] = extend(deep,src,copy);
   }else {

    if (copy !== undefined) {

    target[name] = copy;
    }
   }
   }
  }
  }

  return target
 }

1、参数判断,若第一个参数为布尔类型,则取为控制是否深度拷贝的参数deep , deep 默认为false;同时 目标元素会是第二个参数

2、复制属性值时,要判断deep参数和 属性值的类型 ; 若 deep为true 且 属性值为对象类型 则递归调用 extend函数 , 否则直接赋值

3、需要区分 数组 和 ‘对象' ,来给 目标对象的属性赋值不同的初始值。如果都是 {} 的话,数组类型的属性值复制到目标元素上会变为 {'0':xx , '1' : xx ...}

结语

一直都是在直接使用 $.extend(),好用但是不是很清楚其中的实现,自己撸一撸,也许实现上还有不严谨的地方,但是觉得收获还是不错的。

以上这篇基于对象合并功能的实现示例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery 判断元素上是否绑定了事件
Oct 28 Javascript
JS 添加千分位与去掉千分位的示例
Jul 11 Javascript
Javasipt:操作radio标签详解
Dec 30 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(一)
Feb 16 Javascript
在javascript中创建对象的各种模式解析
May 16 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
Apr 21 jQuery
web前端开发中常见的多列布局解决方案整理(一定要看)
Oct 15 Javascript
vue.js项目中实用的小技巧汇总
Nov 29 Javascript
javascript和php使用ajax通信传递JSON的实例
Aug 21 Javascript
在Vue methods中调用filters里的过滤器实例
Aug 30 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
Aug 30 Javascript
js实现搜索提示框效果
Sep 05 Javascript
聊聊Vue.js的template编译的问题
Oct 09 #Javascript
Vue组件之全局组件与局部组件的使用详解
Oct 09 #Javascript
Angular2监听页面大小变化的解决方法
Oct 09 #Javascript
JS实现预加载视频音频/视频获取截图(返回canvas截图)
Oct 09 #Javascript
input 标签实现输入框带提示文字效果(两种方法)
Oct 09 #Javascript
详解使用Typescript开发node.js项目(简单的环境配置)
Oct 09 #Javascript
JS中Attr的用法详解
Oct 09 #Javascript
You might like
全世界最小的php网页木马一枚 附PHP木马的防范方法
2009/10/09 PHP
PHP生成迅雷、快车、旋风等软件的下载链接代码实例
2014/05/12 PHP
硬盘浏览程序,保存成网页格式便可使用
2006/12/03 Javascript
测试你的JS的掌握程度的代码
2009/12/09 Javascript
Javascript简单实现可拖动的div
2013/10/22 Javascript
jquery ajax,ashx,json的用法总结
2014/02/12 Javascript
EasyUI,点击开启编辑框,并且编辑框获得焦点的方法
2015/03/01 Javascript
基于Bootstrap的UI扩展 StyleBootstrap
2016/06/17 Javascript
关于JS Lodop打印插件打印Bootstrap样式错乱问题的解决方案
2016/12/23 Javascript
js实现简单的网页换肤效果
2017/01/18 Javascript
jQuery实现的分页功能示例
2017/01/22 Javascript
JavaScript简单计算人的年龄示例
2017/04/15 Javascript
深入理解Vue.js源码之事件机制
2017/09/27 Javascript
vue iview组件表格 render函数的使用方法详解
2018/03/15 Javascript
JS将网址url转化为JSON格式的方法
2018/07/02 Javascript
Vue自定义多选组件使用详解
2020/09/08 Javascript
[02:16]DOTA2英雄基础教程 干扰者
2014/01/15 DOTA
[56:42]VP vs RNG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python isinstance函数介绍
2015/04/14 Python
python Pygame的具体使用讲解
2017/11/03 Python
Python3数字求和的实例
2019/02/19 Python
numpy ndarray 取出满足特定条件的某些行实例
2019/12/05 Python
python opencv实现gif图片分解的示例代码
2019/12/13 Python
PyInstaller将Python文件打包为exe后如何反编译(破解源码)以及防止反编译
2020/04/15 Python
Pycharm在指定目录下生成文件和删除文件的实现
2020/12/28 Python
英国天然有机美容护肤品:Neal’s Yard Remedies
2018/05/05 全球购物
ETO男装官方网店:ETO Jeans
2019/02/28 全球购物
吉力贝官方网站:Jelly Belly
2019/03/11 全球购物
公司中层干部的自我评价分享
2014/03/01 职场文书
春风行动实施方案
2014/03/28 职场文书
电子商务助理求职自荐信
2014/04/10 职场文书
社团活动总结范文
2014/04/26 职场文书
励志演讲稿800字
2014/08/21 职场文书
幼儿园教师师德师风承诺书
2015/04/28 职场文书
金正昆讲礼仪观后感
2015/06/11 职场文书
virtualenv隔离Python环境的问题解析
2022/06/21 Python