其值在内存中占据着固定大小的空间,并被保存在栈内存中。当一个变量向另一个变量复制基本类型的值,会创建这个值的副本,并且我们不能给基本数据类型的值添加属性。其为深拷贝。
我们可以看到,简单的赋值便是浅拷贝,一个对象改变,另一个也随之改变。
1.使用JSON.stringfy();
var obj1 = { a: { b: 10 } }; var obj2 = JSON.parse(JSON.stringify(obj1)); obj2.a.b = 20; console.log(obj1); //{ a: { b: 10 } } console.log(obj2); //{ a: { b: 20 } } console.log(obj1 === obj2); // false console.log(obj1.a === obj2.a); // false2.使用递归实现
function deepClone(obj){ let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ //判断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);//[2, 2, 3, 4] console.log(b);// [1, 2, 3, 4]当对象中有循环引用时:
即:
var a={c:1,d:2};a.e=a;
设置一个标记,当目前对象已经被克隆过时,则不再循环调用
function deepClone(obj){ mark[obj]=1; let objClone = Array.isArray(obj)?[]:{}; for(key in obj){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj[key]&&typeof obj[key] ==="object"){ if(mark[obj[key]]==1){ objClone[key]=obj[key]; continue; } objClone[key] = deepClone(obj[key]); }else{ //如果不是,简单复制 objClone[key] = obj[key]; } } return objClone; } var a={c:1,d:2}; a.e=a; mark={}; b=deepClone(a); console.log(a);//{c: 1, d: 2, e: {…}} console.log(b);//{c: 1, d: 2, e: {…}}
3.JQuery的extend()。
$.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);//[-1,1,[-1,3],4] console.log(b);//[0,1,[2,3],4]特别说明:concat(),slice()不是深拷贝,因为其只是一级属性是深拷贝,二级属性就不是了。
let a=[0,1,[2,3],4], b=a.slice(); a[0]=-1; a[2][0]=-1; console.log(a);//[-1,1,[-1,3],4] console.log(b);//[0,1,[-1,3],4] let a=[0,1,[2,3],4], b=[].concat(a); a[0]=-1; a[2][0]=-1; console.log(a);//[-1,1,[-1,3],4] console.log(b);//[0,1,[-1,3],4]更多专业前端知识,请上 【猿2048】www.mk2048.com