ITPub博客

首页 > 应用开发 > Javascript > 深拷贝和浅拷贝

深拷贝和浅拷贝

原创 Javascript 作者:ckxllf 时间:2019-09-05 14:42:50 0 删除 编辑

  深拷贝和浅拷贝的知识涉及到堆栈的概念。

  堆栈的概念:

  基本类型:

  名值存储在栈内存中,例如:

  let a = 1;

  引用类型:

  名存在栈内存中,值存在于堆内存中,但是栈内存会提供一个引用的地址指向堆内存中的值;

  总体来说就是栈内存中保持的是基本类型的值,引用类型的“引用”,堆内存中保存的是创建的对象实例。

  浅拷贝:

  b clone了 a

  当修改a的时候,b也会发生改变

  这就是浅拷贝。

  但是基本类型不会受其影响:

  let a = 2;

  let b = a;

  a = 3;

  console.log(a, b) //3,2

  引用类型的数据就会受其影响:

  let a = [0, 1, 2];

  b = a;

  a[0] = 3;

  console.log(a, b) //结果相同

  特别注明: jQuery的extend默认是浅拷贝的方法

  

在这里插入图片描述

  

在这里插入图片描述

  那么我们如何实现深拷贝呢?

  1.使用递归去复制所有层级属性。

  这里封装一个深拷贝的函数

  function deepClone(obj){

  let objClone = Array.isArray(obj)?[]:{};

  if(obj && typeof obj === "object"){

  for(key in obj){

  if(obj.hasOwnProperty(key)){

  //判断obj子元素是否为对象,如果是,递归复制

  if(obj[key] && typeof obj[key]==="object"){

  objClone[key] = deepClone(obj[key]);

  } else { 无锡人流多少钱 http://www.xaytsgyy.com/

  //如果不是对象,简单复制

  objClone[key] = obj[key];

  }

  }

  }

  }

  return objClone;

  }

  let a = [1,2,3,4],

  b = deepClone(a);

  a[2]=100;

  console.log(a,b) //结果不同,b已经脱离a的控制了

  

在这里插入图片描述

  这里再次强调,深拷贝是拷贝对象各个层级的属性!

  我们在试一试数组的slice()方法:

  t a = [1,2,3,4],

  b = a.slice();

  a[0] = 2;

  console.log(a,b) //不相同

  

在这里插入图片描述

  slice()实现了深拷贝?

  别着急下定论,我们在测试一下:

  let a = [1,[2,3],4],

  b = a.slice();

  a[0]=3;

  a[1][0]=4;

  console.log(a,b) //1级属性不相同,2级属性相同

  所以slice()方法并不是真正的深拷贝。

  第一层的属性确实深拷贝,拥有了独立的内存,但更深的属性却仍然公用了地址,所以才会造成上面的问题。同理,concat方法与slice也存在这样的情况,他们都不是真正的深拷贝。这里需要注意一下。

  2.除了递归,我们还可以借用JSON对象的parse和stringify

  function deepClone(obj){

  let _obj = JSON.stringify(obj),

  objClone = JSON.parse(_obj);

  return objClone;

  }

  let a = [0,[1,2],3],

  b = deepClone(a);

  a[0]=3;

  a[1][0]=6;

  console.log(a,b)

  结果如下:

  JSON.stringfly与JSON.parse除了实现深拷贝,还能结合localStorage实现对象数组存储。

  3.除了上面俩种方法之外,我们还可以借用jQuery的extend方法

  $.extend([deep],target,object1[,objectN])

  deep表示是否深拷贝,为true为深拷贝,为false,则为浅拷贝

  traget Object类型,目标对象,其他对象的成员属性将被附加到该对象上。

  object1 objectN可选。 Object类型 第一个以及第N个被合并的对象。

  代码如下:

  

在这里插入图片描述


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69945560/viewspace-2656105/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-16

  • 博文量
    204
  • 访问量
    262650