JavaScript 深层克隆对象详解及实例


Posted in Javascript onNovember 03, 2016

 JavaScript 深层克隆对象

今天做项目,有个需求需要用到深层克隆对象,并且要求在原型链上编程 于是心血来潮索性来复习一下这个知识点,在网上找了相应的知识,

克隆对象,这名词看着高大上,其实也没什么,便是拷贝一个长的一模一样的对象
也许有初学的小伙伴在想,那还不简单么,so easy

var obj1 = {name: 'payen'};

var obj2 = obj1;

这可并不是克隆对象,obj1和obj2根本就是同一个对象,

他俩指向同一个内存地址空间,拿到了同样的一个小房子

这是应为对象是引用值

说到引用值

JavaScript中引用值只有对象

这里注意,数组是特殊的对象,函数也是特殊的可执行对象, 也就是说,它们也是对象 ,所谓深层克隆对象就是说它并不想要同样的房子,房子你也要给我复制一份一模一样的 不知道我这么说大家能不能理解= ̄ω ̄= ,也就是深层克隆对象引用值要拷贝,而相对的浅层克隆对象只要把那个引用值拿过来就好了 ,不明白不要紧,看完代码就理解了

首先来一起看看浅层克隆对象吧

var house = {
  name: 'payen',
  people: {
    father: true,
    mother: true
  }
}
function easyClone(obj){
  var newObj = {};
  for(var prop in obj){
    if(obj.hasOwnProperty(prop)){
      newObj[prop] = obj[prop];
    }
  }
  return newObj;
}
var newHouse = easyClone(house);

不要吐槽我用easy,一时想不起来“浅”英文咋说来着(真不知道我英语六级怎么过的) 。关于那个for-in有一个小性能问题,感兴趣的童鞋可以看看我的另一篇文章

这段代码很简单我就不多解释了

来看看chrome控制台

JavaScript 深层克隆对象详解及实例

看样子很棒的样子

那么我现在做一件事

给新房子加一个人

JavaScript 深层克隆对象详解及实例

看来这个”新房子”并不新啊,不要被变量名字迷惑了所以,有引用值出现,浅层克隆并不好用了

既然如此,我们怎么办呢

既然要得到新的对象,我们创建一个新对象,把旧对象内部的东西,再拷贝到新对象不就得了

还有一个问题如果对象里还有对象呢

那么就继续重复创建添加的过程,很显然是一个循环的过程

不过循环有两种

迭代

递归

毫无疑问递归更胜一筹

在递归循环中,遇到满足终止条件的条件时逐层返回来结束 ,那么我们就可以通过递归逐层查找引用值,直到没有引用值为止
还是看代码吧

var house = {
  name: 'payen',
  people: {
    father: true,
    mother: true,
    child: {
      age: 1
    }
  },
  money: [1000,2000,3000]
}
function deepClone(original, target){
  var target = target || {};// 如果target为undefined或没传参,设置空对象
  for(var prop in original){// 遍历原对象
    if(original.hasOwnProperty(prop)){// 只拷贝对象内部,不考虑原型链
      if(typeof original[prop] === 'object'){// 引用值
        if(Object.prototype.toString.call(original[prop]) === '[object Array]'){
          target[prop] = [];// 处理数组引用值
        }else{
          target[prop] = {};// 处理对象引用值
        }// 可以用三目运算符
        deepClone(original[prop],target[prop]);// 递归克隆
      }else{// 基本值
        target[prop] = original[prop];
      }  
    }
  }
  return target;
}
var newHouse = deepClone(house);

上面写了那个if-else挺适合用三目运算符的,不过我感觉太冗长了,强迫症表示看了很不舒服 ,为了证明它真的深层克隆了,我特意把原始房子变复杂了 ,(我们不考虑函数的深层克隆,麻烦并且意义不大) ,这回它真的是新房子了

JavaScript 深层克隆对象详解及实例

我就不展开了

可以看出来在新对象的引用值改动,旧对象并没有变

在原型链上编程同理

var house = {
  name: 'payen',
  people: {
    father: true,
    mother: true,
    child: {
      age: 1
    }
  },
  money: [1000,2000,3000]
}
Object.prototype.cloneTo = function(obj){
  var obj = obj || {};
  for(var prop in this){
    if(this.hasOwnProperty(prop)){
      if(typeof this[prop] === 'object'){
        if(Object.prototype.toString.call(this[prop]) === '[object Array]'){
          obj[prop] = [];
        }else{
          obj[prop] = {};
        }
        this[prop].cloneTo(obj[prop]);
      }else{
        obj[prop] = this[prop];
      }
    }
  }
  return obj;
}
var newHouse = {};
house.cloneTo(newHouse);

感谢阅读,希望能帮到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
JavaScript类库D
Oct 24 Javascript
整理8个很棒的 jQuery 倒计时插件和教程
Dec 12 Javascript
Javascript表单验证要注意的事项
Sep 29 Javascript
javascript中判断json的方法总结
Aug 27 Javascript
第十篇BootStrap轮播插件使用详解
Jun 21 Javascript
Ubuntu 16.04 64位中搭建Node.js开发环境教程
Oct 19 Javascript
js实现淡入淡出轮播切换功能
Jan 13 Javascript
jquery 判断是否支持Placeholder属性的方法
Feb 07 Javascript
从零开始学习Node.js系列教程四:多页面实现数学运算的client端和server端示例
Apr 13 Javascript
JS实现的加减乘除四则运算计算器示例
Aug 09 Javascript
layui实现数据表格table分页功能(ajax异步)
Jul 27 Javascript
浅谈vue生命周期共有几个阶段?分别是什么?
Aug 07 Javascript
jQuery.ajax实现根据不同的Content-Type做出不同的响应
Nov 03 #Javascript
简单学习vue指令directive
Nov 03 #Javascript
Vue.js常用指令汇总(v-if、v-for等)
Nov 03 #Javascript
巧用Vue.js+Vuex制作专门收藏微信公众号的app
Nov 03 #Javascript
原生javascript实现的ajax异步封装功能示例
Nov 03 #Javascript
探索Vue.js component内容实现
Nov 03 #Javascript
javascript跨域请求包装函数与用法示例
Nov 03 #Javascript
You might like
咖啡与牛奶
2021/03/03 冲泡冲煮
Eclipse中php插件安装及Xdebug配置的使用详解
2013/04/25 PHP
PDO::commit讲解
2019/01/27 PHP
Laravel框架模型的创建及模型对数据操作示例
2019/05/07 PHP
php高性能日志系统 seaslog 的安装与使用方法分析
2020/02/29 PHP
关于图片验证码设计的思考
2007/01/29 Javascript
用JQuery模仿淘宝的图片放大镜显示效果
2011/09/15 Javascript
用RadioButten或CheckBox实现div的显示与隐藏
2013/09/21 Javascript
内容滑动切换效果jquery.hwSlide.js插件封装
2016/07/07 Javascript
利用JS实现数字增长
2016/07/28 Javascript
聊一聊jQuery插件uploadify使用方法
2016/08/24 Javascript
JavaScript实现向select下拉框中添加和删除元素的方法
2017/03/07 Javascript
JavaScript基于扩展String实现替换字符串中index处字符的方法
2017/06/13 Javascript
微信小程序支付之c#后台实现方法
2017/10/19 Javascript
three.js中文文档学习之通过模块导入
2017/11/20 Javascript
JavaScript实现二叉树定义、遍历及查找的方法详解
2017/12/20 Javascript
Es6 Generator函数详细解析
2018/02/24 Javascript
Vue Autocomplete 自动完成功能简单示例
2019/05/25 Javascript
JS实现动态星空背景效果
2019/11/01 Javascript
jquery实现直播弹幕效果
2019/11/28 jQuery
python中二维阵列的变换实例
2014/10/09 Python
python Pygame的具体使用讲解
2017/11/03 Python
python字符串的方法与操作大全
2018/01/30 Python
django限制匿名用户访问及重定向的方法实例
2018/02/07 Python
pytz格式化北京时间多出6分钟问题的解决方法
2019/06/21 Python
Python基于BeautifulSoup和requests实现的爬虫功能示例
2019/08/02 Python
OpenCV+face++实现实时人脸识别解锁功能
2019/08/28 Python
python爬虫 requests-html的使用
2020/11/30 Python
丝芙兰中国官方商城:SEPHORA中国
2018/01/10 全球购物
婚纱摄影师求职信
2014/03/07 职场文书
音乐兴趣小组活动总结
2014/07/07 职场文书
2014年秋季开学寄语
2014/08/02 职场文书
国家奖学金获奖感言
2014/08/16 职场文书
房屋出租协议书范本(标准版)
2014/09/24 职场文书
思想纪律作风整顿剖析材料
2014/10/11 职场文书
解决golang 关于全局变量的坑
2021/05/06 Golang