JS实现深拷贝(包括日期类型的和正则类型)

JS如何实现深拷贝

背景知识:
基本数据类型:undefined、null、number、boolean、string、symbol
引用数据类型:object(数组、函数等都属于引用数据类型)

常用的实现深拷贝的方法:

1、使用JSON.stringify
const arr = [
	{ a: new Date(), aa: new RegExp('\\w+'), aaa: function() { console.log('aaa function') } }, 
	{ b: 'qwe' }, 
	{ c: [null, undefined] }, 
	{ d: [{ da: 1, db: { dba: 123 }}] }
]
const copyArr = JSON.parse(JSON.stringify(arr))
console.log(copyArr)

不足:
1、日期类型的数据会直接变成字符串的形式,而不是对象的形式
2、正则类型的数据会变成空对象{}
3、函数会丢失
优点:能够满足大部分的业务需求、代码量少

2、自定义实现深拷贝函数

相比较于JSON.stringify的方式增加了日期和正则类型的数据的拷贝

function clone(obj) {
  // 当null NaN undefined number string等基本数据类型时直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj
  }
  // Date类型
  if (obj instanceof Date) {
    const copy = new Date()
    copy.setTime(obj.getTime())
    return copy
  }
  // 正则类型类型
  if (obj instanceof RegExp) {
    const Constructor = obj.constructor
    return new Constructor(obj)
  }
  // 如果是数组等引用数据类型
  if (obj instanceof Array || obj instanceof Object) {
    const copyObj = Array.isArray(obj) ? [] : {}
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        copyObj[key] = clone(obj[key])
      }
    }
    return copyObj
  }
}

不足:没有实现函数的复制

3、使用lodash.js中的cloneDeep函数

具体可以见官网的示例:lodash.js cloneDeep函数

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<script>
  var objects = [
	{ a: new Date(), aa: new RegExp('\\w+'), aaa: function() { console.log('aaa function') } }, 
	{ b: 'qwe' }, 
	{ c: [null, undefined] }, 
	{ d: [{ da: 1, db: { dba: 123 }}] }
]
  var deep = _.cloneDeep(objects);
  console.log(deep);

为什么会有深拷贝与浅拷贝?
引用数据类型的数据相对于基本数据类型的数据而言,由于其存储的方式不一样,因而有深浅拷贝之分。

基本数据类型的值是直接存放在栈内存当中的,引用数据类型在栈内存中存放的是该对象在堆内存中的起始地址。如对象c在栈内存中的值就是c[0]在堆中的地址。

因此深浅拷贝都是相对于引用数据类型来说的,浅拷贝是只复制了对象的地址,深拷贝是重新在内存中开辟一块地址用于存储值。图中的var d = c就属于浅拷贝,对象c与d的指向的地址是一样的。
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值