JavaScript对象的浅拷贝与深拷贝实例分析


Posted in Javascript onJuly 25, 2018

本文实例讲述了JavaScript对象的浅拷贝和深拷贝。分享给大家供大家参考,具体如下:

1、浅拷贝

仅仅复制对象的引用,而不是对象本身。

var person = {
  name: 'Alice',
  friends: ['Bruce', 'Cindy']
}
var student = {
  id: 30
}
student = simpleClone(person, student);
student.friends.push('David');
alert(person.friends);
function simpleClone(oldObj, newObj) {
  var newObj = newObj || {};
  for (var i in oldObj)
    newObj[i] = oldObj[i];
  return newObj;
}

使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun,测试运行结果:

JavaScript对象的浅拷贝与深拷贝实例分析

给子对象的数组类型的属性添加一个新值,父对象的该属性值也被篡改。

2、深拷贝

把复制的对象所引用的全部对象都复制一遍,能够实现真正意义上的数组和对象的拷贝。

浅拷贝的问题:如果父对象的属性值为一个数组或另一个对象,那么实际上子对象获得的只是一个内存地址,而不是对父对象的真正拷贝,因此存在父对象被篡改的可能。

解决方法:使用深拷贝。

var person = {
  name: 'Alice',
  friends: ['Bruce', 'Cindy']
}
var student = {
  id: 30
}
student = deepClone(person, student);
student.friends.push('David');
alert(person.friends); // 'Bruce', 'Cindy'
function deepClone(oldObj, newObj) {
  var newObj = newObj || {};
  newObj = JSON.parse(JSON.stringify(oldObj));
  return newObj;
}

使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun,测试运行结果:

JavaScript对象的浅拷贝与深拷贝实例分析

3、实现深拷贝的方法

1) 方法1:使用JSON.parse()方法

function deepClone(oldObj, newObj) {
  var newObj = newObj || {};
  newObj = JSON.parse(JSON.stringify(oldObj));
  return newObj;
}

优点:

简单易用。

缺点:

① 会抛弃对象的constructor,即,深拷贝后,不管该对象原来的构造函数是什么,在深拷贝之后都会变成Object。

② 能正确处理的对象只有 Number, String, Boolean, Array,即那些能够被JSON直接表示的数据结构,RegExp对象等无法通过这种方式深拷贝。

2) 方法2:递归拷贝

function deepClone(oldObj, newObj) {
  var newObj = newObj || {};
  for (var i in oldObj) {
    if (typeof oldObj[i] === 'object') {
      newObj[i] = (oldObj[i].constructor === Array) ? [] : {};
      arguments.callee(oldObj[i], newObj[i]);
    }
    else
      newObj[i] = oldObj[i];
  }
  return newObj;
}

问题:当遇到两个互相引用的对象,会出现死循环的情况。

解决方法:在遍历时判断两个对象是否相互引用(如oldObj.property === newObj),如果是则退出循环。

function deepClone(oldObj, newObj) {
  var newObj = newObj || {};
  for (var i in oldObj) {
    var prop = oldObj[i];
    if (prop === newObj)
          continue;
    if (typeof prop === 'object') {
      newObj[i] = (prop.constructor === Array) ? [] : {};
      arguments.callee(prop, newObj[i]);
    }
    else
      newObj[i] = prop;
  }
  return newObj;
}

3) 方法3:使用Object.create()方法

function deepClone(oldObj, newObj) {
  var newObj = newObj || {};
  for (var i in oldObj) {
    var prop = oldObj[i];
    if (prop === newObj)
          continue;
    if (typeof prop === 'object')
      newObj[i] = (prop.constructor === Array) ? [] : Object.create(prop);
    else
      newObj[i] = prop;
  }
  return newObj;
}

4)方法4:使用jQuery.extend()jQuery.fn.extend()

请见:https://3water.com/article/144424.htm

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
使用Firebug对js进行断点调试的图文方法
Apr 02 Javascript
基于JQuery制作可编辑的表格特效
Dec 23 Javascript
javascript 操作符(~、&、|、^、)使用案例
Dec 31 Javascript
jQuery与Ajax以及序列化
Feb 01 Javascript
Ajax使用原生态JS验证用户名是否存在
May 26 Javascript
详解基于Angular4+ server render(服务端渲染)开发教程
Aug 28 Javascript
Vue打包后出现一些map文件的解决方法
Feb 13 Javascript
使用Vue.js开发微信小程序开源框架mpvue解析
Mar 20 Javascript
vue拖拽组件使用方法详解
Dec 01 Javascript
js实现网页同时进行多个倒计时功能
Feb 25 Javascript
vue如何使用外部特殊字体的操作
Jul 30 Javascript
js面向对象封装级联下拉菜单列表的实现步骤
Feb 08 Javascript
Vue与Node.js通过socket.io通信的示例代码
Jul 25 #Javascript
jQuery.extend 与 jQuery.fn.extend的用法及区别实例分析
Jul 25 #jQuery
详解Vue源码学习之callHook钩子函数
Jul 25 #Javascript
详解操作虚拟dom模拟react视图渲染
Jul 25 #Javascript
浅析JS中回调函数及用法
Jul 25 #Javascript
详解使用mpvue开发github小程序总结
Jul 25 #Javascript
详解mpvue开发小程序小总结
Jul 25 #Javascript
You might like
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
2010/07/04 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
PHP 实现页面静态化的几种方法
2017/07/23 PHP
PHP 实现链式操作
2021/03/09 PHP
Js 获取HTML DOM节点元素的方法小结
2009/04/24 Javascript
关于可运行代码无法正常执行的使用说明
2010/05/13 Javascript
JS中Iframe之间传值及子页面与父页面应用
2013/03/11 Javascript
js 实现日期灵活格式化的小例子
2013/07/14 Javascript
javascript中数组中求最大值示例代码
2013/12/18 Javascript
JS实现鼠标点击展开或隐藏表格行的方法
2015/03/03 Javascript
php常见的页面跳转方法汇总
2015/04/15 Javascript
jquery插件NProgress.js制作网页加载进度条
2015/06/05 Javascript
js基于cookie方式记住返回页面用法示例
2016/05/27 Javascript
JavaScript直播评论发弹幕切图功能点集合效果代码
2016/06/26 Javascript
js print打印网页指定区域内容的简单实例
2016/11/01 Javascript
Node.js 8 中的 util.promisify的详解
2017/06/12 Javascript
javaScript封装的各种写法
2017/08/14 Javascript
史上最全JavaScript数组去重的十种方法(推荐)
2017/08/17 Javascript
JS实现简单的抽奖转盘效果示例
2019/02/16 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
vue+elementui 对话框取消 表单验证重置示例
2019/10/29 Javascript
[45:25]OG vs EG 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.22
2019/09/05 DOTA
详解使用python的logging模块在stdout输出的两种方法
2017/05/17 Python
python调用OpenCV实现人脸识别功能
2018/05/25 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
Python3.8中使用f-strings调试
2019/05/22 Python
ghd澳大利亚官方网站:英国最受欢迎的美发工具品牌
2018/05/21 全球购物
机械专业毕业生推荐信范文
2013/11/25 职场文书
销售心得体会
2014/01/02 职场文书
明星员工获奖感言
2014/08/14 职场文书
五五普法心得体会
2014/09/04 职场文书
医院党的群众路线教育实践活动领导班子对照检查材料
2014/09/25 职场文书
公司庆典欢迎词
2015/01/26 职场文书
财政局长个人总结
2015/03/04 职场文书
2015年“世界无车日”活动方案
2015/05/06 职场文书
个人更名证明
2015/06/23 职场文书