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获取URL参数与参数值的示例代码
Dec 20 Javascript
基于JQuery实现的图片自动进行缩放和裁剪处理
Jan 31 Javascript
angularJS提交表单(form)
Feb 09 Javascript
浅谈javascript中call()、apply()、bind()的用法
Apr 20 Javascript
JS+CSS实现的日本门户网站经典选项卡导航效果
Sep 27 Javascript
基于JQuery实现图片上传预览与删除操作
May 24 Javascript
Javascript数组中push方法用法分析
Oct 31 Javascript
JavaScript模板引擎Template.js使用详解
Dec 15 Javascript
Vue 过渡(动画)transition组件案例详解
Jan 22 Javascript
Electron autoUpdater实现Windows安装包自动更新的方法
Dec 24 Javascript
vue spa应用中的路由缓存问题与解决方案
May 31 Javascript
Antd表格滚动 宽度自适应 不换行的实例
Oct 27 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
laravel5.4生成验证码的实例讲解
2017/08/05 PHP
visual studio code 调试php方法(图文详解)
2017/09/15 PHP
Laravel框架实现利用监听器进行sql语句记录功能
2018/06/06 PHP
js获取TreeView控件选中节点的Text和Value值的方法
2012/11/24 Javascript
javascript使用中为什么10..toString()正常而10.toString()出错呢
2013/01/11 Javascript
JavaScript实现网页上的浮动广告的简单方法
2013/06/14 Javascript
Jquery 的outerHeight方法使用介绍
2013/09/11 Javascript
多个jquery.datatable共存,checkbox全选异常的快速解决方法
2013/12/10 Javascript
js的匿名函数使用介绍
2013/12/11 Javascript
JS实现点击复选框将按钮或文本框变为灰色不可用的方法
2015/08/11 Javascript
Node.js中使用socket创建私聊和公聊聊天室
2015/11/19 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
jQuery实现CheckBox全选、全不选功能
2017/01/11 Javascript
jQuery基于事件控制实现点击显示内容下拉效果
2017/03/07 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
jQuery实现的鼠标响应缓冲动画效果示例
2018/02/13 jQuery
Vue.js的动态组件模板的实现
2018/11/26 Javascript
nodejs检测因特网是否断开的解决方案
2019/04/17 NodeJs
vue项目添加多页面配置的步骤详解
2019/05/22 Javascript
pycharm 使用心得(七)一些实用功能介绍
2014/06/06 Python
Python文件去除注释的方法
2015/05/25 Python
详解Python中的相对导入和绝对导入
2017/01/06 Python
python 简单备份文件脚本v1.0的实例
2017/11/06 Python
python多任务及返回值的处理方法
2019/01/22 Python
8段用于数据清洗Python代码(小结)
2019/10/31 Python
Python基础之函数原理与应用实例详解
2020/01/03 Python
Python使用py2neo操作图数据库neo4j的方法详解
2020/01/13 Python
一文弄懂Pytorch的DataLoader, DataSet, Sampler之间的关系
2020/07/03 Python
python实现简单的井字棋游戏(gui界面)
2021/01/22 Python
突破canvas语法限制 让他支持链式语法
2012/12/24 HTML / CSS
护士自荐信
2013/10/25 职场文书
端午节活动策划方案
2014/03/09 职场文书
医院安全生产月活动总结
2014/07/05 职场文书
授权委托书范文
2014/07/31 职场文书
运动员入场词
2015/07/18 职场文书
CSS布局之浮动(float)和定位(position)属性的区别
2021/09/25 HTML / CSS