浅拷贝:按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址,因此其中一个对象改变了这个地址,就会影响到另一个对象。
当 b=a时,
所以修改其中一个对象时,另一个对象也受到影响了。
如果是这样的:
修改其中的一个,对另一个对象没影响,那么这就是深拷贝。
深拷贝:会拷贝所有的属性,并拷贝属性指向的动态分配的内存。
实现深拷贝的方式一:递归
比如:
function deepClone(obj){
let objClone = Array.isArray(obj) ? [] : {};
if(obj && typeof obj === 'object'){
for(key in obj){
if(obj.hasOwnproperty(key)){
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);
打印结果:
JQ 里有个slice方法,看看是不是深拷贝的。
结果:
这样咋一看,有点像。但事实不是真正的深拷贝。
结果:
它的一级属性确实没受影响,但是二级属性确实受到了影响的,所以并不是真正的深拷贝。
实现深拷贝方式二:JSON.striingify 和 JSON.parse。
function deepClone(obj){ let _obj = JSON.stringify(obj); let objClone = JSON.parse(_obj); return objClone; } let a = [0,1,[2,3],4]; b = deepClone(a); a[0] = 1; a[2][0] =1 ; console.log(a,b);
实现深拷贝方式三:JQ里的extend方法
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>ajax</title>
5 </head>
6 <body>
7
8 <script src="https://cdn.staticfile.org/jquery/2.0.0/jquery.min.js"></script>
9 <script type="text/javascript">
10 let a =[0,1,[2,3],4];
11 b = $.extend(true,[],a);
12 a[0] = 1;
13 a[2][0] = 1;
14 console.log(a,b);
15 </script>
16 </body>
17 </html>
结果:
不过JSON的这种方式有缺陷,如:
1 function deepClone(obj){
2 let _obj = JSON.stringify(obj);
3 objClone = JSON.parse(_obj);
4 return objClone;
5 }
6 var objBig = {
7 k:[1,2,3],
8 name: 'objBig',
9 pfy: null,
10 a: undefined,
11 sayName: function(){
12 console.log(this.name);
13 }
14 }
15 aaa = deepClone(objBig);
16 console.log(aaa);
结果:
它会忽略函数跟undefined。