资讯专栏INFORMATION COLUMN

深浅拷贝

yck / 2041人阅读

摘要:好像栗子不是那么好吃,那我们来看看下面的解释吧深浅拷贝深拷贝和浅拷贝只针对像这样的引用类型数据。深拷贝则是开启一个新的栈,两个对象对应两个不同的引用地址,修改一个对象的属性,不会改变另一个对象的属性。

拷贝顾名思义就是复制,但是它并不简单哦,拷贝分为深浅拷贝,那么啥是深拷贝啥是浅拷贝呢,让我们来举个栗子,浅拷贝就是当你拷贝别人的U盘里东西时,却没有新建文件存放在自己的电脑里,直接在里面修改,那么我们就更改了U盘里的内容,深拷贝就是在自己的电脑里新建了文件进行修改,而不会影响到原来的内容。好像栗子不是那么好吃,那我们来看看下面的解释吧!!!

深浅拷贝

1.深拷贝和浅拷贝只针对像Object, Array这样的引用类型数据。

2.浅拷贝是对对象引用地址进行拷贝,并没有开辟新的栈,也就是拷贝后的结果是两个对象指向同一个引用地址,修改其中一个对象的属性,则另一个对象的属性也会改变。

3.深拷贝则是开启一个新的栈,两个对象对应两个不同的引用地址,修改一个对象的属性,不会改变另一个对象的属性。

浅拷贝

直接上栗子吧

var myInfo = {name:"liu",sex:"女"};
var newInfo = myInfo;
console.log(myInfo); //{name:"liu",sex:"女"}
newInfo.sex = "小仙女";
console.log(myInfo); //{name:"liu",sex:"小仙女"}

可以看到newInfo复制了myInfo里的内容,本应他们之间没有联系的,可是为什么当newInfo更改时同时也影响了myInfo?那是因为这只是浅拷贝,newInfo的地址并没有更改,指向同一个栈。

深拷贝

让我们先对比一下下面的两个栗子吧!

var array = [{a:1,b:2},{a:3,b:4}];
var newArray = Object.assign([],array);
newArray.length = 1;
console.log(newArray);  
console.log(array);  
newArray[0].a = 123;
console.log(array[0]); 
function deepClone(obj){    
  if(!obj&& typeof obj!== "object"){      
    return;    
  }    
  var newObj= obj.constructor === Array ? [] : {};    
  for(var key in obj){       
    if(obj[key]){          
      if(obj[key] && typeof obj[key] === "object"){  
        newObj[key] = obj[key].constructor === Array ? [] : {}; 
        //递归
        newObj[key] = deepClone(obj[key]);          
      }else{            
        newObj[key] = obj[key];         
      }       
    }    
  }    
  return newObj; 
}
var array = [{a:1,b:2},{a:3,b:4}];
var newArray = deepClone(array);
console.log(array[0]);
newArray[0].a = 123;
console.log(array[0]);

大家思考一下,这两个栗子会是一样吗?

来公布一下正确答案:
先看第一个栗子
[{a:1,b:2},{a:3,b:4}]
{a: 123, b: 2}
(问号脸)我明明没有更改myInfo的数据啊,这么回事?
因为Object.assign并不是深拷贝,是披着深拷贝外衣的浅拷贝。最多也是Object.assign会拷贝第一层的值,对于第一层的值都是深拷贝,而到第二层的时候就是复制引用。类似的情况还有,slice方法和concat方法等。

来看看第二个
{a:1,b:2}
{a:1,b:2}
两个结果都是一样的,为什么呢?
因为这才是深拷贝啊,newInfo开启了一个新的栈,虽然内容相同,可是他们已经在不同地点了,互不影响。这里我们采用了封装和递归,如果对象属性的值是引用类型(Array,Object),那么对该属性进行深拷贝,直到遍历到属性的值是基本类型为止。好像有点复杂诶,没事,我们还有个简单粗暴的方法!!!

var newArray = JSON.parse(JSON.stringify(array));
console.log(array[0])//{a:1,b:2}
newArray[0].a = 123
console.log(array[0])//{a:1,b:2}

利用JSON解析函数把对象转成字符串,再把字符串转成对象!四不四很简单呀!?

这就是我对于深浅拷贝的了解了,如果有更好的见解要告诉我哦!?

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/89894.html

相关文章

  • JS专题之深浅拷贝

    摘要:在之前的文章专题之数据类型和类型检测中我有讲过,中的数据类型分为两种,基本数据类型和引用数据类型,基本数据类型是保存在栈的数据结构中的是按值访问,所以不存在深浅拷贝问题。 前言 在开发过程中,偶尔会遇到这种场景,拿到一个数据后,你打算对它进行处理,但是你又希望拷贝一份副本出来,方便数据对比和以后恢复数据。 那么这就涉及到了 JS 中对数据的深浅拷贝问题,所谓深浅拷贝,浅拷贝的意思就是,...

    ASCH 评论0 收藏0
  • 深入理解JS深浅拷贝

    摘要:深拷贝相比于浅拷贝速度较慢并且花销较大。所以在赋值完成后,在栈内存就有两个指针指向堆内存同一个数据。结果如下扩展运算符只能对一层进行深拷贝如果拷贝的层数超过了一层的话,那么就会进行浅拷贝那么我们可以看到和展开原算符对于深浅拷贝的结果是一样。 JS中数据类型 基本数据类型: undefined、null、Boolean、Number、String和Symbol(ES6) 引用数据类型:...

    JackJiang 评论0 收藏0
  • 深浅拷贝

    摘要:深复制实现代码如下第一种方法通过递归解析解决第二种方法通过解析解决作者六师兄链接原生深拷贝的实现处理未输入新对象的情况通过方法构造新的对象 深浅拷贝针对的是 对象类型,如果是字符串的数组用[...arr],还是不会影响 要区分针对数组的深浅拷贝(默认情况为里面没有对象的数组),与针对对象的深浅拷贝 JavaScript数组深拷贝和浅拷贝的两种方法 let a1 = [1, 2]; ...

    Karrdy 评论0 收藏0
  • Javascript对象的深浅拷贝

    摘要:开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。高级属性修改深拷贝满足对象的复制,浅拷贝影响原数组。关于对象的深浅拷贝,暂且探索到这里,后续有新发现再进行补充。 showImg(https://segmentfault.com/img/remote/1460000014305581); 开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。其实都是copy。 ...

    qieangel2013 评论0 收藏0
  • 9012年,当我们讨论js深浅拷贝时我们在说些什么?

    摘要:正文讨论深浅拷贝,首先要从的基本数据类型说起根据中的变量类型传递方式,分为值类型和引用类型,值类型变量包括。当你拷贝的对象有多级的时候,就是深拷贝。数据不存在则对其拷贝。 前言: 本文主要阅读对象:对深浅拷贝印象模糊对初级前端,想对js深浅拷贝聊一聊的中级前端。 如果是对这些有完整对认知体系和解决方法的大佬,可以选择略过。 正文: 讨论深浅拷贝,首先要从js的基本数据类型说起: 根据 J...

    xeblog 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<