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 Tabs插件宿主IFRAMES
Jan 01 Javascript
Javascript排序算法之计数排序的实例
Apr 05 Javascript
JS的数组迭代方法
Feb 05 Javascript
jquery配合.NET实现点击指定绑定数据并且能够一键下载
Oct 28 Javascript
vue用addRoutes实现动态路由的示例
Sep 15 Javascript
深入理解Node module模块
Mar 26 Javascript
JavaScript基础教程之如何实现一个简单的promise
Sep 11 Javascript
vue生命周期和react生命周期对比【推荐】
Sep 19 Javascript
微信小程序学习笔记之目录结构、基本配置图文详解
Mar 28 Javascript
JS获取表格视图所选行号的ids过程解析
Feb 21 Javascript
12 种使用Vue 的最佳做法
Mar 30 Javascript
JavaScript 实现拖拽效果组件功能(兼容移动端)
Nov 11 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
MVC模式的PHP实现
2006/10/09 PHP
PHP里的中文变量说明
2011/07/23 PHP
PHP抽象类 介绍
2012/06/13 PHP
使用Appcan客户端自动更新PHP版本号(全)
2015/07/31 PHP
PHP利用APC模块实现大文件上传进度条的方法
2015/10/29 PHP
YII使用url组件美化管理的方法
2015/12/28 PHP
Zend Framework教程之动作的基类Zend_Controller_Action详解
2016/03/07 PHP
thinkPHP实现递归循环栏目并按照树形结构无限极输出的方法
2016/05/19 PHP
PHP大神的十大优良习惯
2016/09/14 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
2019/12/20 PHP
Ajax执行顺序流程及回调问题分析
2012/12/10 Javascript
js中复制行和删除行的操作实例
2013/06/25 Javascript
JS实现仿雅虎首页快捷登录入口及导航模块效果
2015/09/19 Javascript
初步使用Node连接Mysql数据库
2016/03/03 Javascript
关于微信中a链接无法跳转问题
2016/08/02 Javascript
vue实现手机号码抽奖上下滚动动画示例
2017/10/18 Javascript
Vue实现表格中对数据进行转换、处理的方法
2018/09/06 Javascript
vue-cli 使用axios的操作方法及整合axios的多种方法
2018/09/12 Javascript
JQuery Ajax执行跨域请求数据的解决方案
2018/12/10 jQuery
[47:02]2018DOTA2亚洲邀请赛3月29日 小组赛B组 VP VS paiN
2018/03/30 DOTA
从零开始学Python第八周:详解网络编程基础(socket)
2016/12/14 Python
django基础之数据库操作方法(详解)
2017/05/24 Python
Python使用pickle模块存储数据报错解决示例代码
2018/01/26 Python
Python实现找出数组中第2大数字的方法示例
2018/03/26 Python
图解Python变量与赋值
2018/04/03 Python
python 列表递归求和、计数、求最大元素的实例
2018/11/28 Python
python中round函数保留两位小数的方法
2020/12/04 Python
用CSS3的box-reflect来制作倒影效果
2016/11/15 HTML / CSS
浅谈pc和移动端的响应式的使用
2019/01/03 HTML / CSS
美国最大的宠物药店:1-800-PetMeds
2016/10/02 全球购物
开业庆典邀请函
2014/01/08 职场文书
大学生军训自我鉴定
2014/02/12 职场文书
科长个人四风问题整改措施思想汇报
2014/10/13 职场文书
2014年大学学生会工作总结
2014/12/02 职场文书
幼儿园个人总结
2015/02/28 职场文书
MySQL事务的隔离级别详情
2022/07/15 MySQL