javascript对浅拷贝和深拷贝的详解


Posted in Javascript onOctober 14, 2016

下面小编就为大家带来一篇浅谈JavaScript中面向对象的的深拷贝和浅拷贝。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。

1.浅拷贝:复制一份引用,所有引用对象都指向一份数据,并且都可以修改这份数据。

2.深拷贝(复杂):复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。

这里画一个简单的图来加深理解:

javascript对浅拷贝和深拷贝的详解

一、数组的深浅拷贝

在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变,这就导致了问题的发生。

var arr = ["One","Two","Three"];
var arrto = arr;
arrto[1] = "test";
document.writeln("数组的原始值:" + arr + "<br />");//Export:数组的原始值:One,test,Three
document.writeln("数组的新值:" + arrto + "<br />");//Export:数组的新值:One,test,Three

像上面的这种直接赋值的方式就是浅拷贝,很多时候,这样并不是我们想要得到的结果,其实我们想要的是arr的值不变,不是吗?

方法一:js的slice函数

var arr = ["One","Two","Three"];
var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln("数组的原始值:" + arr + "<br />");//Export:数组的原始值:One,Two,Three
document.writeln("数组的新值:" + arrtoo + "<br />");//Export:数组的新值:One,set Map,Three

方法二:js的concat方法

var arr = ["One","Two","Three"];
var arrtooo = arr.concat();
arrtooo[1] = "set Map To";
document.writeln("数组的原始值:" + arr + "<br />");//Export:数组的原始值:One,Two,Three
document.writeln("数组的新值:" + arrtooo + "<br />");//Export:数组的新值:One,set Map To,Three

二、对象的深浅拷贝

var a={name:'yy',age:26};
var b=new Object();
b.name=a.name;
b.age=a.age;
a.name='xx';
console.log(b);//Object { name="yy", age=26}
console.log(a);//Object { name="xx", age=26}

就是把对象的属性遍历一遍,赋给一个新的对象。

var deepCopy= function(source) { 
var result={};
for (var key in source) {
 result[key] = typeof source[key]==='object'? deepCoyp(source[key]): source[key];
 } 
 return result; 
}

举一个jQuery中的例子:

jQuery.extend = jQuery.fn.extend = function() {//1.将extend方法扩展到JQ(函数)下边:扩展静态方法
 //2. jQuery.fn.extend 把extend扩展到jq.fn下 且jQuery.fn = jQuery.prototype 扩展实例方法
 // 1.2.功能相似
 var options, name, src, copy, copyIsArray, clone, //定义一些变量
 target = arguments[0] || {}, 
 //目标元素是【0】第一个元素$.extend( a , { name : 'hello' } , { age : 30 } );
 i = 1, //第一个元素的位置
 length = arguments.length,//第一个个对象的元素
 deep = false; //是否是深拷贝 默认 false不是

 // Handle a deep copy situation 看是不是深拷贝情况
 if ( typeof target === "boolean" ) { //是布尔值 
 deep = target;
 target = arguments[1] || {}; //目标元素是第二个$.extend( true , a , b )
 // skip the boolean and the target
 i = 2;
 }

 // Handle case when target is a string or something (possible in deep copy) 看参数正确不
 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
 // 当目标不是对象或者不是函数的时候
 target = {}; //变成一个空的jason
 }

 // extend jQuery itself if only one argument is passed看是不是插件情况
 if ( length === i ) { //只写了一个对象 要把这个对象扩展到jq源码上 静态方法 或者是实例方法
 target = this; //this 是$ 或者 $();
 --i;
 }
// 可能有多个对象情况
 for ( ; i < length; i++ ) {
 // Only deal with non-null/undefined values
 if ( (options = arguments[ i ]) != null ) {//看后边的对象是否都有值
 // Extend the base object
 for ( name in options ) {
 src = target[ name ];
 copy = options[ name ];

 // Prevent never-ending loop
 if ( target === copy ) {//防止循环引用 
  continue;//跳出本次循环继续执行
  // $.extend( a , { name : a } ) );循环引用 a也是一个对象
 }

 // Recurse if we're merging plain objects or arrays深拷贝
 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
  // 是深拷贝 且需有var b = { name : { age : 30 } }; 且b必须是对象自变量(jason) 或者是个数组
  
  //递归
  if ( copyIsArray ) { //数组
  copyIsArray = false;
  clone = src && jQuery.isArray(src) ? src : []; //定义一个空数组

  } else {//jason
  clone = src && jQuery.isPlainObject(src) ? src : {};//看原有的属性有没有且是不是jason定义一个空jason
  }
  // var a = { name : { job : 'it' } }; 看有没有原有的属性 有的话在原有的上边添加
  // var b = { name : {age : 30} };
  // $.extend( true , a , b );//a继承b
  // console.log( a ); a{ name:{ job : 'it' ,age : 30}} 如果只有一个{} 则只有,age : 30
  // Never move original objects, clone(a) them
  target[ name ] = jQuery.extend( deep, clone, copy ); 
  //调用函数本身进行进一步的递归处理 

 // Don't bring in undefined values浅拷贝
 } else if ( copy !== undefined ) {
  target[ name ] = copy; //直接复制因为里边没有对象
 }
 }
 }
 }

 // Return the modified object
 return target;
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery html()等方法介绍
Nov 18 Javascript
javascript判断iphone/android手机横竖屏模式的函数
Dec 20 Javascript
jQuery实现的兼容性浮动层示例
Aug 02 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
Sep 09 Javascript
Bootstrap幻灯片轮播图支持触屏左右手势滑动的实现方法
Oct 13 Javascript
详解jQuery中的DOM操作
Dec 23 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
Jul 31 Javascript
ES6学习笔记之map、set与数组、对象的对比
Mar 01 Javascript
React 使用browserHistory项目访问404问题解决
Jun 01 Javascript
详解Vue取消eslint语法限制
Aug 04 Javascript
vue项目中将element-ui table表格写成组件的实现代码
Jun 12 Javascript
详细介绍解决vue和jsp结合的方法
Feb 06 Javascript
jQuery web 组件 后台日历价格、库存设置的代码
Oct 14 #Javascript
第一次接触神奇的Bootstrap
Oct 14 #Javascript
js仿手机页面文件下拉刷新效果
Oct 14 #Javascript
前端js实现文件的断点续传 后端PHP文件接收
Oct 14 #Javascript
js关于getImageData跨域问题的解决方法
Oct 14 #Javascript
AngularJS 与Bootstrap实现表格分页实例代码
Oct 14 #Javascript
深入学习js瀑布流布局
Oct 14 #Javascript
You might like
php一些公用函数的集合
2008/03/27 PHP
php类的定义与继承用法实例
2015/07/07 PHP
用Javascript实现锚点(Anchor)间平滑跳转
2009/09/08 Javascript
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
2010/09/14 Javascript
常用的JavaScript模板引擎介绍
2015/02/28 Javascript
nodejs 中模拟实现 emmiter 自定义事件
2016/02/22 NodeJs
AngularJS实现星星等级评分功能
2016/09/24 Javascript
说说node中的可读流和可写流的区别
2018/06/01 Javascript
JS实现图片轮播效果实例详解【可自动和手动】
2019/04/04 Javascript
javascript 高级语法之继承的基本使用方法示例
2019/11/11 Javascript
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
element-ui tree结构实现增删改自定义功能代码
2020/08/31 Javascript
[01:11]steam端dota2实名认证操作流程视频
2021/03/11 DOTA
Python的加密模块md5、sha、crypt使用实例
2014/09/28 Python
python获取当前计算机cpu数量的方法
2015/04/18 Python
对Python中DataFrame按照行遍历的方法
2018/04/08 Python
pytorch实现用Resnet提取特征并保存为txt文件的方法
2019/08/20 Python
numpy.random.shuffle打乱顺序函数的实现
2019/09/10 Python
Python实现PyPDF2处理PDF文件的方法示例
2019/09/25 Python
Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例
2019/12/18 Python
Python写捕鱼达人的游戏实现
2020/03/31 Python
使用python实现名片管理系统
2020/06/18 Python
python线程池 ThreadPoolExecutor 的用法示例
2020/10/10 Python
Python远程linux执行命令实现
2020/11/11 Python
python 实现Requests发送带cookies的请求
2021/02/08 Python
一套中级Java程序员笔试题
2015/01/14 面试题
Ruby中的保护方法和私有方法与一般面向对象程序设计语言的一样吗
2013/05/01 面试题
好家长事迹材料
2014/01/23 职场文书
弘扬雷锋精神活动演讲稿
2014/03/04 职场文书
求职自荐信的格式
2014/04/07 职场文书
商务代表岗位职责
2015/02/15 职场文书
2016年村党支部公开承诺书
2016/03/24 职场文书
读《工匠精神》有感:热爱工作,精益求精
2019/12/28 职场文书
如何使用分区处理MySQL的亿级数据优化
2021/06/18 MySQL
高性能跳频抗干扰宽带自组网电台
2022/02/18 无线电
游戏《东方异文石:爱亚利亚黎明》正式版发布
2022/04/03 其他游戏