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中的isXX系列是否继续使用的分析
Apr 16 Javascript
A标签触发onclick事件而不跳转的多种解决方法
Jun 27 Javascript
javascript实现控制文字大中小显示
Apr 28 Javascript
分享jQuery插件的学习笔记
Jan 14 Javascript
在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)
Jan 20 Javascript
移动端滑动插件Swipe教程
Oct 16 Javascript
jquery 判断div show的状态实例
Dec 03 Javascript
微信小程序 wx.uploadFile无法上传解决办法
Dec 14 Javascript
BootStrap的两种模态框方式
May 10 Javascript
原生JavaScript来实现对dom元素class的操作方法(推荐)
Aug 16 Javascript
详解Vue.js Mixins 混入使用
Sep 15 Javascript
vue项目前端知识点整理【收藏】
May 13 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正则表达式获取内容所有链接
2015/07/24 PHP
php简单复制文件的方法
2016/05/09 PHP
PHP 年月日的三级联动实例代码
2017/05/24 PHP
javascript call和apply方法
2008/11/24 Javascript
Prototype RegExp对象 学习
2009/07/19 Javascript
JQuery Tips(4) 一些关于提高JQuery性能的Tips
2009/12/19 Javascript
理解Javascript_15_作用域分配与变量访问规则,再送个闭包
2010/10/20 Javascript
在VS2008中使用jQuery智能感应的方法
2010/12/30 Javascript
JavaScript高级程序设计(第3版)学习笔记12 js正则表达式
2012/10/11 Javascript
从JQuery源码分析JavaScript函数的apply方法与call方法
2014/09/25 Javascript
javascript实现手机震动API代码
2015/08/05 Javascript
jQuery 获取页面li数组并删除不在数组中的key
2016/08/02 Javascript
jQuery选择器总结之常用元素查找方法
2016/08/04 Javascript
Angular设置title信息解决SEO方面存在问题
2016/08/19 Javascript
js实现上传图片预览方法
2016/10/25 Javascript
微信小程序开发(二)图片上传+服务端接收详解
2017/01/11 Javascript
微信小程序本地缓存数据增删改查实例详解
2017/05/24 Javascript
vue中多个倒计时实现代码实例
2019/03/27 Javascript
[29:59]完美世界DOTA2联赛PWL S3 Forest vs access 第二场 12.11
2020/12/13 DOTA
在Django的模型中添加自定义方法的示例
2015/07/21 Python
Python实现压缩与解压gzip大文件的方法
2016/09/18 Python
Tensorflow实现AlexNet卷积神经网络及运算时间评测
2018/05/24 Python
Linux 修改Python命令的方法示例
2018/12/03 Python
django框架实现一次性上传多个文件功能示例【批量上传】
2019/06/19 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
简单了解python关键字global nonlocal区别
2020/09/21 Python
python tkinter实现连连看游戏
2020/11/16 Python
Python自动化测试基础必备知识点总结
2021/02/07 Python
CSS3中的transform属性进行2D和3D变换的基本用法
2016/05/12 HTML / CSS
全球最大的户外用品零售商之一:The House
2018/06/12 全球购物
大专学生推荐信范文
2013/11/19 职场文书
运动会通讯稿400字
2014/01/28 职场文书
思想品德自我评价
2014/02/04 职场文书
医师定期考核实施方案
2014/05/07 职场文书
2016年党课培训学习心得体会
2016/01/07 职场文书
JavaScript 去重和重复次数统计
2021/03/31 Javascript