深拷贝和浅拷贝的问题

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

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

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

   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 = 30result.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还有一种方法是实现插件机制的  暂不表 













本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部