一篇文章彻底搞懂浅拷贝和深拷贝(深拷贝浅拷贝)

此篇文章中也会简单阐述到 栈堆基本数据类型引用数据类型 ,因为这些概念能更好的让你理解深拷贝与浅拷贝。

如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力。

举个栗子,有时候开发中会遇到一下情况

let a = [1,2,3,4,5] let b = a console.log(a === b) // true 因为栈内存a、栈内存b访问的同一块堆内存 // 那么问题来了 a[0] = '我变了昂' console.log(b) // ['我变了昂',2,3,4,5] 怎么肥事 //因为b = a等同于b是a的快捷方式,他们指向同一块内存,所以取出来的值一定会随着a的变化 b也可以成为引用类型数据

面试常问,基本数据类型有哪些,number,string,boolean,null,undefined五类。

引用数据类型(Object类)有常规名值对的无序对象{a:1},数组[1,2,3],以及函数等。

基本数据类型与引用数据类型的区别基本数据类型

例如 let a = 1

一篇文章彻底搞懂浅拷贝和深拷贝(深拷贝浅拷贝)(1)

当你b深拷贝a复制时,栈内存会新开辟一个内存,例如这样:

一篇文章彻底搞懂浅拷贝和深拷贝(深拷贝浅拷贝)(2)

所以当你此时修改a=2,对b并不会造成影响,因为此时的b有独立的内存空间了,不受a的影响了。当然,let a=1,b=a;虽然b不受a影响,但这也算不上深拷贝,因为深拷贝本身只针对较为复杂的object类型数据。

引用数据类型

引用数据类型–名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值 ,我们以上面浅拷贝的例子画个图:

一篇文章彻底搞懂浅拷贝和深拷贝(深拷贝浅拷贝)(3)

其实上图表示b=a 其实是将b的堆内存指向与a相同的内存

实现深拷贝的方法

1.根据数据类型封装一个方法

function deepClone(obj) { let newobj = obj instanceof Array ? [] : {} // 或者 Array.isArray(obj)?[]: {} // 上边的方法是判断obj的数据类型 是对象还是数组 if (typeof obj !== 'obj') { return obj // 判断是不是基本数据类型,如果是直接返回 } else { // 数组、类数组、对象 for(var key in obj) { newobj[key] = typeof obj[key] === 'object' ? deepClone(obj[key]) : obj[key] // 判断obj[key]是不是数组或者对象,如果是则传进deepClone,否则直接返回 } } return newobj }

2.使用JSON的stringify()、parse()

const deepClone = (obj) => { return JSON.parse(JSON.stringify(obj)) }

3.使用JQ的$.extends

$.extend( [deep ], target, object1 [, objectN ] )

deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝

target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。

object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

let a=[0,1,[2,3],4], b=$.extend(true,[],a); a[0]=1; a[2][0]=1; console.log(a,b)

不知道有没有在魔都的小伙伴,你们会房子的时候会不会特别烦,觉得生活好难啊。

另外那个平台租房子便宜一些,昨天遇到一个中介,隔板间都要问我要2800,我的钱是大风刮来的吗?

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页