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 相关文章推荐
推荐11款jQuery开发的复选框和单选框美化插件
Aug 02 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
Apr 12 Javascript
jQuery判断checkbox(复选框)是否被选中以及全选、反选实现代码
Feb 21 Javascript
一系列Bootstrap导航条使用方法分享
Apr 29 Javascript
Bootstrap组件系列之福利篇几款好用的组件(推荐二)
Jul 12 Javascript
Node.js 日志处理模块log4js
Aug 28 Javascript
jQuery ajax MD5实现用户注册即时验证功能
Oct 11 Javascript
jQuery EasyUi 验证功能实例解析
Jan 06 Javascript
详解Vue.use自定义自己的全局组件
Jun 14 Javascript
JavaScript字符串转数字的5种方法及遇到的坑
Jul 16 Javascript
对TypeScript库进行单元测试的方法
Jul 18 Javascript
js中Map和Set的用法及区别实例详解
Feb 15 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
PHP字符串处理的10个简单方法
2010/06/30 PHP
php获取文件大小的方法
2014/02/26 PHP
PHP树形结构tree类用法示例
2019/02/01 PHP
PHP文件上传小程序 适合初学者学习!
2019/05/23 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
2019/12/20 PHP
Jquery 动态循环输出表格具体方法
2013/11/23 Javascript
JavaScript也谈内存优化
2014/06/06 Javascript
无需 Flash 使用 jQuery 复制文字到剪贴板
2016/04/26 Javascript
Vuex模块化实现待办事项的状态管理
2017/03/15 Javascript
单击按钮发送验证码,出现倒计时的简单实例
2017/03/17 Javascript
微信小程序图片宽100%显示并且不变形
2017/06/21 Javascript
Vue中封装input组件的实例详解
2017/10/17 Javascript
使用vue-cli+webpack搭建vue开发环境的方法
2017/12/22 Javascript
vue 实现类似淘宝星级评分的示例
2018/03/01 Javascript
vue实现的上传图片到数据库并显示到页面功能示例
2018/03/17 Javascript
js中事件对象和事件委托的介绍
2019/01/21 Javascript
layer.msg()去掉默认时间,实现手动关闭的方法
2019/09/12 Javascript
JavaScript find()方法及返回数据实例
2020/04/30 Javascript
[08:38]DOTA2-DPC中国联赛 正赛 VG vs Elephant 选手采访
2021/03/11 DOTA
python获取从命令行输入数字的方法
2015/04/29 Python
Windows系统下多版本pip的共存问题详解
2017/10/10 Python
深入理解Django的中间件middleware
2018/03/14 Python
利用python和百度地图API实现数据地图标注的方法
2019/05/13 Python
Python Request类源码实现方法及原理解析
2020/08/17 Python
韩国最大的购物网站:Gmarket
2019/06/20 全球购物
Moss Bros官网:英国排名第一的西装店
2020/02/26 全球购物
Brasty罗马尼亚:购买手表、香水、化妆品、珠宝
2020/04/21 全球购物
空指针到底是什么
2012/08/07 面试题
大学生职业生涯规划书模板
2014/01/03 职场文书
公务员培训自我鉴定
2014/02/01 职场文书
先进典型事迹材料
2014/12/29 职场文书
学习党史心得体会2016
2016/01/23 职场文书
《夹竹桃》教学反思
2016/02/23 职场文书
golang 在windows中设置环境变量的操作
2021/04/29 Golang
Oracle以逗号分隔的字符串拆分为多行数据实例详解
2021/07/16 Oracle
4种方法python批量修改替换列表中元素
2022/04/07 Python