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 相关文章推荐
jQuery AJAX回调函数this指向问题
Feb 08 Javascript
基于jquery的关于动态创建DOM元素的问题
Dec 24 Javascript
js去除重复字符串两种实现方法
Jan 09 Javascript
javascript中比较字符串是否相等的方法
Jul 23 Javascript
Select标签下拉列表二级联动级联实例代码
Feb 07 Javascript
js给table赋值的实例代码
Oct 13 Javascript
Bootstrap基本样式学习笔记之按钮(4)
Dec 07 Javascript
jQuery中animate的几种用法与注意事项
Dec 12 Javascript
React-Native实现ListView组件之上拉刷新实例(iOS和Android通用)
Jul 11 Javascript
Node.js如何实现注册邮箱激活功能 (常见)
Jul 23 Javascript
详解Vue webapp项目通过HBulider打包原生APP(vue+webpack+HBulider)
Feb 02 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
Feb 26 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
超强分页类2.0发布,支持自定义风格,默认4种显示模式
2007/01/02 PHP
php whois查询API制作方法
2011/06/23 PHP
浅谈web上存漏洞及原理分析、防范方法(文件名检测漏洞)
2013/06/29 PHP
ThinkPHP框架任意代码执行漏洞的利用及其修复方法
2014/07/04 PHP
Thinkphp多文件上传实现方法
2014/10/31 PHP
php类常量用法实例分析
2015/07/09 PHP
解决在laravel中auth建立时候遇到的问题
2019/10/15 PHP
jQuery中iframe的操作(点击按钮新增窗口)
2016/04/20 Javascript
在web中js实现类似excel的表格控件
2016/09/01 Javascript
js 提交form表单和设置form表单请求路径的实现方法
2016/10/25 Javascript
JS定时器实现数值从0到10来回变化
2016/12/09 Javascript
从零学习node.js之文件操作(三)
2017/02/21 Javascript
浅析Vue 生命周期
2018/06/21 Javascript
Vue.js上传图片到阿里云OSS存储的方法示例
2018/12/13 Javascript
JS script脚本中async和defer区别详解
2020/06/24 Javascript
一起来了解一下JavaScript的预编译(小结)
2021/03/01 Javascript
py2exe 编译ico图标的代码
2013/03/08 Python
利用Python绘制数据的瀑布图的教程
2015/04/07 Python
Python获取统计自己的qq群成员信息的方法
2019/11/15 Python
Tensorflow 定义变量,函数,数值计算等名字的更新方式
2020/02/10 Python
Python绘制动态水球图过程详解
2020/06/03 Python
装上这 14 个插件后,PyCharm 真的是无敌的存在
2021/01/11 Python
python爬取抖音视频的实例分析
2021/01/19 Python
Html5实现文件异步上传功能
2017/05/19 HTML / CSS
新西兰优惠网站:Treat Me
2019/07/04 全球购物
英国电气世界:Electrical World
2019/09/08 全球购物
石油大学毕业生自荐信
2014/01/28 职场文书
销售员个人求职的自我评价
2014/02/10 职场文书
租赁意向书范本
2014/04/01 职场文书
党员自我评议对照检查材料
2014/09/27 职场文书
我们的节日元宵节活动总结
2015/02/06 职场文书
有关信念的名言语录集锦
2019/12/06 职场文书
python 实现mysql自动增删分区的方法
2021/04/01 Python
Java实现简易的分词器功能
2021/06/15 Java/Android
go goroutine 怎样进行错误处理
2021/07/16 Golang
各国货币符号大全
2022/02/17 杂记