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 相关文章推荐
关于this和self的使用说明
Aug 01 Javascript
js中if语句的几种优化代码写法
Mar 12 Javascript
JS 按钮点击触发(兼容IE、火狐)
Aug 07 Javascript
JavaScript 事件对象介绍
Apr 13 Javascript
JavaScript中的ajax功能的概念和示例详解
Oct 17 Javascript
详解windows下vue-cli及webpack 构建网站(三)使用组件
Jun 17 Javascript
vue封装第三方插件并发布到npm的方法
Sep 25 Javascript
JS实现不用中间变量temp 实现两个变量值得交换方法
Feb 04 Javascript
详解处理bootstrap4不支持远程静态框问题
Jul 20 Javascript
angular6根据environments配置文件更改开发所需要的环境的方法
Mar 06 Javascript
JS实现图片轮播效果实例详解【可自动和手动】
Apr 04 Javascript
JS实现横向轮播图(中级版)
Jan 18 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中预定义的6种接口介绍
2015/05/12 PHP
5款适合PHP使用的HTML编辑器推荐
2015/07/03 PHP
Symfony2框架学习笔记之表单用法详解
2016/03/18 PHP
swoole和websocket简单聊天室开发
2017/11/18 PHP
PHP常用函数之base64图片上传功能详解
2019/10/21 PHP
PHP简单实现图片格式转换(jpg转png,gif转png等)
2019/10/30 PHP
网页javascript精华代码集
2007/01/24 Javascript
一个选择最快的服务器转向代码
2009/04/27 Javascript
js 获取坐标 通过JS得到当前焦点(鼠标)的坐标属性
2013/01/04 Javascript
JavaScript中为什么null==0为false而null大于=0为true(个人研究)
2013/09/16 Javascript
Jquery $.getJSON 在IE下的缓存问题解决方法
2014/10/10 Javascript
深入探寻javascript定时器
2015/01/02 Javascript
js实现分享到随页面滚动而滑动效果的方法
2015/04/10 Javascript
javascript创建对象、对象继承的实用方式详解
2016/03/08 Javascript
node.js从数据库获取数据
2016/05/08 Javascript
解决vue里碰到 $refs 的问题的方法
2017/07/13 Javascript
jQuery实现可编辑表格并生成json结果(实例代码)
2017/07/19 jQuery
基于vue.js无缝滚动效果
2018/01/25 Javascript
AngularJS 事件发布机制
2018/08/28 Javascript
jQuery实现点击图标div循环放大缩小功能
2018/09/30 jQuery
JavaScript中this函数使用实例解析
2020/02/21 Javascript
浅谈vue的第一个commit分析
2020/06/08 Javascript
vue 判断页面是首次进入还是再次刷新的实例
2020/11/05 Javascript
js定时器出现第一次延迟的原因及解决方法
2021/01/04 Javascript
[01:06] DOTA2英雄背景故事第三期之秩序法则光之守卫
2020/07/07 DOTA
django从请求到响应的过程深入讲解
2018/08/01 Python
详解python深浅拷贝区别
2019/06/24 Python
使用Keras建立模型并训练等一系列操作方式
2020/07/02 Python
澳大利亚最早和最古老的巨型游戏专家:Yardgames
2020/02/20 全球购物
公务员培训自我鉴定
2013/09/19 职场文书
生物科学系大学生的自我评价
2013/12/20 职场文书
大学生文员专业个人求职信范文
2014/01/05 职场文书
善意的谎言事例
2014/02/15 职场文书
ktv筹备计划书
2014/05/03 职场文书
家长会欢迎标语
2014/06/24 职场文书
天猫活动策划方案
2014/08/21 职场文书