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 相关文章推荐
javascript replace()正则替换实现代码
Feb 26 Javascript
JS实现Enter键跳转及控件获得焦点
Aug 12 Javascript
了解了这些才能开始发挥jQuery的威力
Oct 10 Javascript
jquery Easyui快速开发总结
Aug 20 Javascript
jQuery实现下拉框功能实例代码
May 06 Javascript
javascript学习笔记_浅谈基础语法,类型,变量
Sep 19 Javascript
AngularJS封装指令方法详解
Dec 12 Javascript
jQuery开源组件BootstrapValidator使用详解
Jun 29 jQuery
浅谈React + Webpack 构建打包优化
Jan 23 Javascript
AngularJS实现与后台服务器进行交互的示例讲解
Aug 13 Javascript
vue.js父子组件通信动态绑定的实例
Sep 28 Javascript
在js代码拼接dom对象到页面上的模板总结
Oct 21 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模拟HTTP认证
2006/10/09 PHP
php遍历目录输出目录及其下的所有文件示例
2014/01/27 PHP
Drupal7 form表单二次开发要点与实例
2014/03/02 PHP
twig里使用js变量的方法
2016/02/05 PHP
yii2 数据库读写分离配置示例
2017/02/10 PHP
CodeIgniter框架验证码类库文件与用法示例
2017/03/18 PHP
Laravel5.5 动态切换多语言的操作方式
2019/10/25 PHP
TP5框架实现自定义分页样式的方法示例
2020/04/05 PHP
禁止直接访问php文件代码分享
2020/05/05 PHP
模仿JQuery sortable效果 代码有错但值得看看
2009/11/05 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
2013/05/03 Javascript
点击弹出层外区域关闭弹出层jquery特效示例
2013/08/25 Javascript
JS和JQuery实现雪花飘落效果
2017/11/30 jQuery
谈谈vue中mixin的一点理解
2017/12/12 Javascript
详解JavaScript中的数组合并方法和对象合并方法
2018/05/11 Javascript
浅谈Node.js 沙箱环境
2018/05/15 Javascript
JS精确判断数据类型代码实例
2019/12/18 Javascript
vue 使用微信jssdk,调用微信相册上传图片功能
2020/11/13 Javascript
[01:12:08]LGD vs OG 2019国际邀请赛淘汰赛 胜者组 BO3 第一场 8.24
2019/09/10 DOTA
Python使用cx_Oracle模块将oracle中数据导出到csv文件的方法
2015/05/16 Python
Flask框架实现给视图函数增加装饰器操作示例
2018/07/16 Python
Python中如何使用if语句处理列表实例代码
2019/02/24 Python
详解Python 调用C# dll库最简方法
2019/06/20 Python
python 返回一个列表中第二大的数方法
2019/07/09 Python
Django文件存储 自己定制存储系统解析
2019/08/02 Python
python3中布局背景颜色代码分析
2020/12/01 Python
HTML5中图片之间的缝隙完美解决方法
2017/07/07 HTML / CSS
软件测试工程师面试问题精选
2016/10/28 面试题
英语自我评价范文
2014/01/24 职场文书
医学专业大学生求职信
2014/07/12 职场文书
个人委托书范本
2014/09/13 职场文书
四风专项整治工作情况汇报
2014/10/28 职场文书
二年级上册数学教学计划
2015/01/20 职场文书
奖金申请报告模板
2015/05/15 职场文书
团队拓展训练感想
2015/08/07 职场文书
送给客户微信问候语!
2019/07/04 职场文书