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 getJSON 处理json数据的代码
Jul 26 Javascript
Javascript公共脚本库系列(一): 弹出层脚本
Feb 24 Javascript
jquery ajax 局部无刷新更新数据的实现案例
Feb 08 Javascript
jQuery插件Slider Revolution实现响应动画滑动图片切换效果
Jun 05 Javascript
JavaScript获取当前时间向前推三个月的方法示例
Feb 04 Javascript
JS实现搜索关键词的智能提示功能
Jul 07 Javascript
详谈构造函数加括号与不加括号的区别
Oct 26 Javascript
JavaScript实现的简单Tab点击切换功能示例
Jul 06 Javascript
详解JavaScript对数组操作(添加/删除/截取/排序/倒序)
Apr 28 Javascript
编写一个javascript元循环求值器的方法
Apr 14 Javascript
vant 解决tab切换插件标题样式自定义的问题
Nov 13 Javascript
微信小程序实现简单购物车功能
Dec 30 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
第十三节 对象串行化 [13]
2006/10/09 PHP
phpmyadmin 访问被拒绝的真实原因
2009/06/15 PHP
centos 5.6 升级php到5.3的方法
2011/05/14 PHP
如何用phpmyadmin设置mysql数据库用户的权限
2012/01/09 PHP
PHP两种快速排序算法实例
2015/02/15 PHP
PDO::errorInfo讲解
2019/01/28 PHP
微信公众平台开发教程①获取用户Openid及个人信息图文详解
2019/04/10 PHP
jquery遍历input取得input的name
2009/04/27 Javascript
js算法中的排序、数组去重详细概述
2013/10/14 Javascript
Google Dart编程语法和基本类型学习教程
2013/11/27 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
2014/06/15 Javascript
JavaScript高仿支付宝倒计时页面及代码实现
2016/10/21 Javascript
js+canvas实现动态吃豆人效果
2017/03/22 Javascript
基于Datatables跳转到指定页的简单实例
2017/11/09 Javascript
Vue2.0 实现单选互斥的方法
2018/04/13 Javascript
Angular使用Restful的增删改
2018/12/28 Javascript
VUE+Element环境搭建与安装的方法步骤
2019/01/24 Javascript
详解微信小程序之一键复制到剪切板
2019/04/24 Javascript
微信小程序中限制激励式视频广告位显示次数(实现思路)
2019/12/06 Javascript
Vue动态加载图片在跨域时无法显示的问题及解决方法
2020/03/10 Javascript
Vue+Element UI 树形控件整合下拉功能菜单(tree + dropdown +input)
2020/08/28 Javascript
浅谈python中的面向对象和类的基本语法
2016/06/13 Python
python实现换位加密算法的示例
2018/10/14 Python
python 顺时针打印矩阵的超简洁代码
2018/11/14 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
2019/01/15 Python
python opencv 二值化 计算白色像素点的实例
2019/07/03 Python
Python模块常用四种安装方式
2020/10/20 Python
南威尔士家居商店:Leekes
2016/10/25 全球购物
Juice Beauty官网:有机美容产品,护肤与化妆品
2020/06/13 全球购物
新员工培训个人的自我评价
2013/10/09 职场文书
公开服务承诺制度
2014/03/26 职场文书
《青山处处埋忠骨》教学反思
2014/04/22 职场文书
工作证明格式及范本
2014/09/12 职场文书
预备党员群众路线思想汇报2014
2014/10/25 职场文书
2014年化妆品销售工作总结
2014/12/01 职场文书
Nginx实现高可用集群构建(Keepalived+Haproxy+Nginx)
2021/05/27 Servers