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选择器简明总结(含用法实例,一目了然)
Apr 25 Javascript
JavaScript中数组继承的简单示例
Jul 29 Javascript
javascript模块化简单解析
Apr 07 Javascript
手机端图片缩放旋转全屏查看PhotoSwipe.js插件实现
Aug 25 Javascript
jquery实现的table排序功能示例
Mar 10 Javascript
Vue.js render方法使用详解
Apr 05 Javascript
React之PureComponent的使用作用
Jul 10 Javascript
vue实现底部菜单功能
Jul 24 Javascript
在vue中实现点击选择框阻止弹出层消失的方法
Sep 15 Javascript
详解js静态检查工具eslint配置文件
Nov 23 Javascript
Vue使用Proxy监听所有接口状态的方法实现
Jun 07 Javascript
基于JavaScript实现控制下拉列表
May 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
加强版phplib的DB类
2008/03/31 PHP
使用XDebug调试及单元测试覆盖率分析
2011/01/27 PHP
FireFox浏览器使用Javascript上传大文件
2013/10/30 PHP
PHP禁止个别IP访问网站
2013/10/30 PHP
PHP多个图片压缩成ZIP的方法
2020/08/18 PHP
laravel框架中表单请求类型和CSRF防护实例分析
2019/11/23 PHP
一个cssQuery对象 javascript脚本实现代码
2009/07/21 Javascript
js+HTML5实现canvas多种颜色渐变效果的方法
2015/06/05 Javascript
JS获取下拉框显示值和判断单选按钮的方法
2015/07/09 Javascript
jquery按回车键实现表单提交的简单实例
2016/05/25 Javascript
详解Node.js项目APM监控之New Relic
2017/05/12 Javascript
关于Vue Webpack2单元测试示例详解
2017/08/14 Javascript
JS实现点击复选框变更DIV显示状态的示例代码
2017/12/18 Javascript
js获取html页面代码中图片地址的实现代码
2018/03/05 Javascript
解决vue 引入子组件报错的问题
2018/09/06 Javascript
Vue代码整洁之去重方法整理
2019/08/06 Javascript
[03:23:49]2016.12.17日完美“圣”典全回顾
2016/12/19 DOTA
python关键字and和or用法实例
2015/05/28 Python
django开发之settings.py中变量的全局引用详解
2017/03/29 Python
使用Python3制作TCP端口扫描器
2017/04/17 Python
python3.6+django2.0开发一套学员管理系统
2018/03/03 Python
利用Pycharm断点调试Python程序的方法
2018/11/29 Python
tensorflow保持每次训练结果一致的简单实现
2020/02/17 Python
python MultipartEncoder传输zip文件实例
2020/04/07 Python
PyCharm 2020.2.2 x64 下载并安装的详细教程
2020/10/15 Python
用Python 执行cmd命令
2020/12/18 Python
python中使用asyncio实现异步IO实例分析
2021/02/26 Python
三年级科学教学反思
2014/01/29 职场文书
爱国主义演讲稿
2014/05/07 职场文书
2014年学校工会工作总结
2014/12/06 职场文书
独生子女证明范本
2015/06/19 职场文书
搞笑的婚礼主持词
2015/06/29 职场文书
教师反邪教心得体会
2016/01/15 职场文书
Nginx tp3.2.3 404问题解决方案
2021/03/31 Servers
mysql的单列多值存储实例详解
2022/04/05 MySQL
mysql数据库如何转移到oracle
2022/12/24 MySQL