如何区分深拷贝与浅拷贝,针对js数据引用类型,以数组a,数组b为例:
假设数组b是复制数组a后拿到的,
浅拷贝:a,b相互影响(修改a的值影响b的值,同理b影响a)
深拷贝:a,b各自独立(互不影响)。
原理涉及到栈堆,基本数据类型与引用数据类型,自行查阅。
1.借用JSON对象的parse和stringify
var a = [1, 2, 3]; //浅拷贝 var b = a; b.push(4); console.log(a); //[1,2,3,4] console.log(b); //[1,2,3,4] //深拷贝 var c =JSON.parse(JSON.stringify(obj)); c.push(4); console.log(a); //[1,2,3] console.log(c); //[1,2,3,4]
2.借用jquery的extend方法。
$.extend( [deep ], target, object1 [, objectN ] )
deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝
target Object类型 目标对象,其他对象的成员属性将被附加到该对象上。
object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。
var a=[1,2,3]; //深拷贝 var b=$.extend(true,[],a); a.push(4); console.log(a);//[1,2,3,4] console.log(b);//[1,2,3]
3.递归递归去复制所有层级属性。
这么我们封装一个深拷贝的函数(PS:只是一个基本实现的展示,并非最佳实践);
function deepClone(obj){ let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ if(obj.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } } } return objClone; } let a=[1,2,3,4], b=deepClone(a); a[0]=2; console.log(a,b);