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 相关文章推荐
jQuery+CSS 实现随滚动条增减的汽水瓶中的液体效果
Sep 26 Javascript
jQuery源码解读之removeAttr()方法分析
Feb 20 Javascript
javascript实现状态栏文字首尾相接循环滚动的方法
Jul 22 Javascript
JS控制层作圆周运动的方法
Jun 20 Javascript
Jquery针对tr td的一些实用操作方法(必看篇)
Oct 05 Javascript
Vue 2.0 服务端渲染入门介绍
Mar 29 Javascript
vue select二级联动第二级默认选中第一个option值的实例
Jan 10 Javascript
浅谈如何使用webpack构建多页面应用
May 30 Javascript
js replace 全局替换的操作方法
Jun 12 Javascript
Vue组件实现触底判断
Jun 26 Javascript
Selenium执行Javascript脚本参数及返回值过程详解
Apr 01 Javascript
在vue中嵌入外部网站的实现
Nov 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之字符串变相相减的代码
2007/03/19 PHP
php下foreach提示Warning:Invalid argument supplied for foreach()的解决方法
2014/11/11 PHP
PHP生成随机密码方法汇总
2015/08/27 PHP
尽可能写"友好"的"Javascript"代码
2007/01/09 Javascript
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
Javascript优化技巧(文件瘦身篇)
2008/01/28 Javascript
jquery 事件对象属性小结
2010/04/27 Javascript
document.getElementById方法在Firefox与IE中的区别
2010/05/18 Javascript
JQuery选择器特辑 详细小结
2012/05/14 Javascript
setTimeout的延时为0时多个浏览器的区别
2012/05/23 Javascript
json属性名为什么要双引号(个人猜测)
2014/07/31 Javascript
jQuery 插件开发指南
2014/11/14 Javascript
JQuery表单验证插件EasyValidator用法分析
2014/11/15 Javascript
jQuery快速实现商品数量加减的方法
2017/02/06 Javascript
微信小程序 this和that详解及简单实例
2017/02/13 Javascript
JavaScript实现各种排序的代码详解
2017/08/28 Javascript
Js中将Long转换成日期格式的实现方法
2018/06/05 Javascript
JavaScript实现简单轮播图效果
2018/12/01 Javascript
浅谈Vuex注入Vue生命周期的过程
2019/05/20 Javascript
javascript设计模式 ? 享元模式原理与用法实例分析
2020/04/15 Javascript
JavaScript代码简化技巧实例解析
2020/09/09 Javascript
使用wxpython实现的一个简单图片浏览器实例
2014/07/10 Python
tensorflow实现KNN识别MNIST
2018/03/12 Python
python3+PyQt5重新实现QT事件处理程序
2018/04/19 Python
Python实现的json文件读取及中文乱码显示问题解决方法
2018/08/06 Python
python GUI图形化编程wxpython的使用
2019/07/19 Python
python常用运维脚本实例小结
2020/02/14 Python
Python自动发送和收取邮件的方法
2020/08/12 Python
html5默认气泡修改的代码详解
2020/03/13 HTML / CSS
四方通行旅游网:台湾订房、出国旅游
2017/09/20 全球购物
启动一个线程是用run()还是start()
2016/12/25 面试题
2014年检验员工作总结
2014/11/19 职场文书
服务明星事迹材料
2014/12/29 职场文书
2015大学生求职信范文
2015/03/20 职场文书
mysql死锁和分库分表问题详解
2021/04/16 MySQL
忆童年!用Python实现愤怒的小鸟游戏
2021/06/07 Python