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 相关文章推荐
Javascript的一种模块模式
Mar 22 Javascript
js常用代码段整理
Nov 30 Javascript
ie支持function.bind()方法实现代码
Dec 27 Javascript
js添加table的行和列 具体实现方法
Jul 22 Javascript
jquery判断小数点两位和自动删除小数两位后的数字
Mar 19 Javascript
JavaScript设计模式之工厂方法模式介绍
Dec 28 Javascript
BootstrapTable+KnockoutJS自定义T4模板快速生成增删改查页面
Aug 01 Javascript
javascript工厂模式和构造函数模式创建对象方法解析
Dec 30 Javascript
vue父组件点击触发子组件事件的实例讲解
Feb 08 Javascript
JavaScript观察者模式原理与用法实例详解
Mar 10 Javascript
使用Vue实现一个树组件的示例
Nov 06 Javascript
解决vue使用vant轮播组件swipe + flex时文字抖动问题
Jan 07 Vue.js
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执行速度全攻略
2006/10/09 PHP
实现了一个PHP5的getter/setter基类的代码
2007/02/25 PHP
php 批量生成html,txt文件的实现代码
2013/06/26 PHP
判断页面是关闭还是刷新的js代码
2007/01/28 Javascript
初学Javascript的一些总结
2008/11/03 Javascript
JS解析json数据并将json字符串转化为数组的实现方法
2012/12/25 Javascript
『jQuery』取指定url格式及分割函数应用
2013/04/22 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
Javascript 赋值机制详解
2014/11/23 Javascript
JS实现随页面滚动显示/隐藏窗口固定位置元素
2016/02/26 Javascript
微信小程序开发之实现选项卡(窗口顶部TabBar)页面切换
2016/11/25 Javascript
bootstrap datetimepicker日期插件使用方法
2017/01/13 Javascript
JavaScript设计模式之策略模式详解
2017/06/09 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
AngularJS创建一个上传照片的指令实例代码
2018/02/24 Javascript
es6 symbol的实现方法示例
2019/04/02 Javascript
vue 保留两位小数 不能直接用toFixed(2) 的解决
2020/08/07 Javascript
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
[03:11]2014DOTA2国际邀请赛-VG掉入败者组 独家专访357
2014/07/19 DOTA
[01:44]《为梦想出发》—联想杯DOTA2完美世界全国高校联赛
2015/09/30 DOTA
windows10系统中安装python3.x+scrapy教程
2016/11/08 Python
Python 调用Java实例详解
2017/06/02 Python
Python 3实战爬虫之爬取京东图书的图片详解
2017/10/09 Python
python对于requests的封装方法详解
2019/01/03 Python
django2.0扩展用户字段示例
2019/02/13 Python
python算法与数据结构之单链表的实现代码
2019/06/27 Python
Python爬虫:url中带字典列表参数的编码转换方法
2019/08/21 Python
python GUI库图形界面开发之PyQt5单选按钮控件QRadioButton详细使用方法与实例
2020/02/28 Python
python Canny边缘检测算法的实现
2020/04/24 Python
python爬虫使用requests发送post请求示例详解
2020/08/05 Python
销售自我评价
2013/10/22 职场文书
审计主管岗位职责
2014/01/31 职场文书
第一批党的群众路线教育实践活动工作总结
2014/03/03 职场文书
市场营销专业毕业生求职信
2014/03/26 职场文书
检讨书范文
2015/01/27 职场文书
讲文明倡议书
2015/04/29 职场文书