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 相关文章推荐
ExtJS的FieldSet的column列布局
Nov 20 Javascript
js之ActiveX控件使用说明 new ActiveXObject()
Mar 03 Javascript
jQuery及JS实现循环中暂停的方法
Feb 02 Javascript
JavaScript每天定时更换皮肤样式的方法
Jul 01 Javascript
AngularJS中的Directive实现延迟加载
Jan 25 Javascript
浅析jQuery Ajax请求参数和返回数据的处理
Feb 24 Javascript
jquery datatable服务端分页
Aug 31 Javascript
AngularJs验证重复密码的方法(两种)
Nov 25 Javascript
vue-cli入门之项目结构分析
Apr 20 Javascript
Bootstrap3.3.7导航栏下拉菜单鼠标滑过展开效果
Oct 31 Javascript
layer.close()关闭进度条和Iframe窗的方法
Aug 17 Javascript
微信小程序图表插件wx-charts用法实例详解
May 20 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 常见郁闷问题答解
2006/11/25 PHP
解析如何在PHP下载文件名中解决乱码的问题
2013/06/20 PHP
5款适合PHP使用的HTML编辑器推荐
2015/07/03 PHP
一文掌握PHP Xdebug 本地与远程调试(小结)
2019/04/23 PHP
Yii2框架操作数据库的方法分析【以mysql为例】
2019/05/27 PHP
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
jquery ui dialog里调用datepicker的问题
2009/08/06 Javascript
html 锁定页面(js遮罩层弹出div效果)
2009/10/27 Javascript
javascript面向对象的方式实现的弹出层效果代码
2010/01/28 Javascript
关于jQuery $.isNumeric vs. $.isNaN vs. isNaN
2013/04/15 Javascript
兼容IE和FF的图片上传前预览js代码
2013/05/28 Javascript
一个小例子解释如何来阻止Jquery事件冒泡
2014/07/17 Javascript
jQuery中animate用法实例分析
2015/03/09 Javascript
详解Webwork中Action 调用的方法
2016/02/02 Javascript
jQuery遍历节点树方法分析
2016/09/08 Javascript
js 能实现监听F5页面刷新子iframe 而父页面不刷新的方法
2016/11/09 Javascript
Vue过滤器的用法和自定义过滤器使用
2017/02/08 Javascript
详解vue-router2.0动态路由获取参数
2017/06/14 Javascript
简述jQuery Easyui一些用法
2017/08/01 jQuery
Bootstrap table使用方法记录
2017/08/23 Javascript
vue 动态改变静态图片以及请求网络图片的实现方法
2018/02/07 Javascript
vue--vuex详解
2019/04/15 Javascript
Angular Excel 导入与导出的实现代码
2019/04/17 Javascript
Layui表格行工具事件与数据回填方法
2019/09/13 Javascript
[48:52]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第一局
2016/02/25 DOTA
Python实现获取网站PR及百度权重
2015/01/21 Python
python数据批量写入ScrolledText的优化方法
2018/10/11 Python
使用python进行波形及频谱绘制的方法
2019/06/17 Python
python实现视频读取和转化图片
2019/12/10 Python
Django URL参数Template反向解析
2020/11/24 Python
数据库测试通常都包括哪些方面
2015/11/30 面试题
个人求职简历的自我评价范文
2013/10/09 职场文书
医院辞职信范文
2014/01/17 职场文书
法制宣传实施方案
2014/03/13 职场文书
golang slice元素去重操作
2021/04/30 Golang
JavaScript继承的三种方法实例
2021/05/12 Javascript