深拷贝和浅拷贝的问题

关于深拷贝和前拷贝的问题我觉得平时在项目中会经常用到,大家也比较熟悉;

下面从几个方面来说一下这个知识点吧;

1,基本的概念 ,原理

2,几种深浅拷贝的方法 

3,实际的应用场景和实现


首先我们来谈谈 深拷贝和浅拷贝的概念;

基本类型的复制(都是在栈里的复制操作)

例如 var a=0;  var b=a ;   这里的b拿a的值就是直接从栈里复制了一份出来 ,完全独立的副本;

这就是拷贝 ,无所谓深浅直说;

深拷贝 和浅拷贝是存在于引用类型上的 ;

例如 var a=[1,2,3,4,5]  var b=a; 此时的a 保存是一个内存地址(堆里空间的指针) , b被a赋值也只是赋值了一个地址;

此时 这种情况就算是浅拷贝

对一个对象拷贝的不够彻底 ,没有把里面的嵌套的 对象完全的拷贝下来 比如:

var a =[ {obj:"obj"},1,2,3]  var b=[...a];  现在b对于a 复制了 一层  ,数组里的对象里的地址a和b还是共用;

此时 这种情况就算是浅拷贝

对于一个对象完全实现了深层次的拷贝,完完全全独立的实现了一个副本;

此时 这种情况就算是深拷贝


再来说几种深浅拷贝的方法 

前拷贝:

1,... 使用 扩展运算符可以使得 对象复制一层 ;

2,for循环实现一层拷贝;

例如

var a=[ 1,2,3,4,5]

var b=[],

for( var  i=0; i<a.lenth;i++) {

   b[i]=a[i]

3,数组的concat;  这也只是一种数组的前拷贝的方法  



深拷贝的方法 

1, json方法

var test ={
	  	name:{
	  	 xing:{ 
	  	     first:'张',
	  	     second:'李'
	  	},
	  	ming:'老头'
	  },
	  age :40,
	  friend :['隔壁老王','宋经纪','同事']
	 }
	  var result = JSON.parse(JSON.stringify(test))
	  result.age = 30
	  result.name.xing.first = '往'
	  result.friend.push('fdagldf;ghad')
	  console.dir(test)
	  console.dir(result)

这种方法 只能复制不包含Function 和Date类型的 对象;这两种类型 会自己做转换;导致两个对象不一致;并且原型链也丢失了;

2,循环递归 

var china = {
	  	nation : '中国',
	  	birthplaces:['北京','上海','广州'],
	  	skincolr :'yellow',
	  	friends:['sk','ls']
	  }
	  //深复制,要想达到深复制就需要用递归
	  function deepCopy(o,c){
	    var c = c || {}
	    for(var i in o){
	    if(typeof o[i] === 'object'){
	  	   	   	  //要考虑深复制问题了
                      if(o[i].constructor === Array){
                    	//这是数组
                    	c[i] =[]
                    }else{
                    	//这是对象
                    	c[i] = {}
                    }
                    deepCopy(o[i],c[i])
	  	   	   }else{
	  	   	   	 c[i] = o[i]
	  	   	   }
	  	   }
	  	   return c
	  }
	  var result = {name:'result'}
	  result = deepCopy(china,result)
	  console.dir(result)

这种实现比较彻底;实现一个独立的副本;


关于深浅拷贝的实际应用 大约就是jq的extend方法;

这是两个函数的合并方法;解释一下这个方法的用法:

1, $.extend( true, object1, object2 );

第2个对象已有的 key为基准 第1个对象合并到第2个对象; 就是说 两个对象都相同的key,那么以第2个对象为准 ,冲掉了第1个key对应的value;   所有的key都会被继承过来合并; 这就是深拷贝的实现;

2, $.extend( object1, object2 );

这种就是浅拷贝了; 和第一种用法 都一样,,,但是只有第一层的key会继承并合并;

这个api还有一种方法是实现插件机制的  暂不表 












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值