浅拷贝:按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址,因此其中一个对象改变了这个地址,就会影响到另一个对象。

 

 

 

 当 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。

 

posted on 2020-12-09 16:40  你这个梦,有点大  阅读(130)  评论(0编辑  收藏  举报