深拷贝和浅拷贝

深拷贝和浅拷贝,顾名思义就是对拷贝出来的数据有深浅之分,其实深浅拷贝只是对对象而言,因为在js的存储中,存储数据的方式有两种,栈内存和堆内存。
1、原始数据类型直接存储在栈中,占据空间小、大小比较稳定,属于被频繁使用数据,所以放入栈中存储;
2、引用数据类型存储在堆中,占据空间大、大小不固定 在栈内存中只是存了一个地址来表示对堆内存中的引用。

浅拷贝

定义

对于基本数据类型的成员变量,浅拷贝直接进行值传递,也就是将属性值复制了一份给新的成员变量;
对于引用数据类型的成员变量,比如成员变量是数组、某个类的对象等,浅拷贝就是引用的传递,也就是将成员变量的引用(内存地址)复制了一份给新的成员变量,他们指向的是同一个事例。在一个对象修改成员变量的值,会影响到另一个对象中成员变量的值。

用法

一、直接赋值
将旧对象的变量名直接赋值给新的对象变量,那么旧对象的属性值一改变,新对象也会改,因为只拷贝了内存地址

二、调用Object.assign()
该方法第一个参数是新对象,第二个参数是旧对象,旧对象中的属性值如果也是对象,那么新对象只是拷贝了内存地址

三、…对象扩展运算符
运用扩展运算符将旧对象在一个新的空对象中展开,如果旧对象中的属性值是对象,那么新对象也是浅拷贝而已

四、for循环遍历对象,将旧对象的属性值依次赋值给新对象,如果旧对象中属性值是一个对象,也只是浅拷贝

深拷贝

定义

对于基本数据类型,深拷贝复制所有基本数据类型的成员变量的值;
对于引用数据类型的成员变量,深拷贝申请新的存储空间,并复制该引用对象所引用的对象,也就是将整个对象复制下来。所以在一个对象修改成员变量的值,不会影响到另一个对象成员变量的值。

用法

一、通过递归的方式实现深拷贝

function deepCopy(data){
  var _data; // 初始化结果,因为结果可能为js任意类型,所以没有赋值.
  // 1. 先验证data是什么类型的数据
 // 如果是基本数据类型,那么直接赋值_data
  if(!(data instanceof Object)){  // 如果是基本数据类型
  _data = data    // 直接赋值
  return _data    /// 输出赋值结果,结束下面语句
}
  if(Array.isArray(data)){  // 验证是不是数组 如果是数组 则进行if语句里面赋值空数组,不是的话直接进行下次判断.
  _data = []   // 对_data赋值空数组
}
  // 验证data是否为对象,如果是对象 则进行if语句里面赋值空对象,不是的话直接进行下次判断.
  if(data.constructor === Object){
  _data = {}  // 对_data赋值为空对象
}
  // 2. 将data中内容添加到 _data中
  for(var i in data){
  // 如果 data[i] 是数组或者对象,则需要进一步深拷贝,所以再次执行deepCopy
  // 将deepCopy() 的返回值 赋值给_data
  _data[i] = deepCopy(data[i])
  }
  return _data
}

二、使用JSON.stringify和JSON.parse

用JSON.stringify(obj)把对象转换成字符串,再用JSON.parse(obj)把字符串转换成新的对象

三、使用函数库lodash的_.cloneDeep()

四、通过JQuery的extend方法实现深拷贝

  • 22
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值