JS的深拷贝和浅拷贝
1、数据类型
首先JS分为基础类型和引用类型两种数据类型,基础数据类型赋值时是【传值】,而引用数据类型赋值时是【传址】,所以引用数据类型赋值时新旧值会相互影响,称之浅拷贝。
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。基础类型:number、string、boolean、null、undefined、symbol
引用类型:Object(Array,Date,RegExp,Function)
它们有个区别 —— 保存位置不同。基本数据类型保存在栈内存中;引用数据类型保存在堆内存中,然后在栈内存中保存了一个对堆内存中实际对象的引用,即数据在堆内存中的地址。
为什么基本数据类型保存在栈中,而引用数据类型保存在堆中?
1)堆比栈大,栈比堆速度快;
2)基本数据类型比较稳定,而且相对来说占用的内存小;
3)引用数据类型大小是动态的,而且是无限的,引用值的大小会改变,不能把它放在栈中,否则会降低变量查找的速度,因此放在变量栈空间的值是该对象存储在堆中的地址,地址的大小是固定的,所以把它存储在栈中对变量性能无任何负面影响;
4)堆内存是无序存储,可以根据引用直接获取;
2、浅拷贝与深拷贝
浅拷贝和深拷贝都只针对于引用数据类型,浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,新旧对象改变时相互影响;但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
3、造成浅拷贝的情况
1)引用类型赋值
var obj ={a:1,b:2,c:3}; var obj1= obj; obj1.a=5; console.log(obj); //{a: 5, b: 2, c: 3} console.log(obj1); //{a: 5, b: 2, c: 3} obj.b=6; console.log(obj); //{a: 5, b: 6, c: 3} console.log(obj1); //{a: 5, b: 6, c: 3}
2)对象作为函数参数传递
var obj ={a:1,b:2,c:3}; fn=(obj)=>{ var obj2= obj; obj2.a=5; }; fn(obj); console.log(obj);//{a: 5, b: 2, c: 3}
ps:如果引用赋值后将对象置空,则相互不受影响
var obj = {a:1,b:2,c:3}; var obj3 = obj; obj = {}; obj.a = 5; console.log(obj3);//{a: 1, b: 2, c: 3} console.log(obj); //{a: 5}
4、如何实现深拷贝:不同的写法及情况
第一级深拷贝,以后级别浅拷贝
1)解构赋值
var obj = {a:{i:1,j:2,k:3},b:2,c:3}; var obj1 = {...obj} obj1.b=5; console.log(obj);//{a:{i:1,j:2,k:3},b:2,c:3};
obj1.a.i=5; console.log(obj);//{a:{i:5,j:2,k:3},b:2,c:3};
2)Object.assign()
var obj = {a:{i:1,j:2,k:3},b:2,c:3}; var obj2 = Object.assign({},obj); obj2.b=5; console.log(obj);//{a:{i:1,j:2,k:3},b:2,c:3};
obj2.a.i=5; console.log(obj);//{a:{i:5,j:2,k:3},b:2,c:3};
深拷贝
1)递归
function deepCopy=()=>{
}
2)json
3)Object.create()
5、另:数组怎么写
slice contact 解构 Array.from

更多精彩