美文网首页
【03】手动实现深拷贝

【03】手动实现深拷贝

作者: 李俊佚 | 来源:发表于2021-02-24 12:20 被阅读0次

在上文中,已经提到了深浅拷贝的概念,以及常用的深浅拷贝的方法。这里进行一个简单的回顾:

  • 改变了一个变量的值,其他变量也一并改变的原因是引用类型数据,栈中存放的是地址,两个变量用了同一份堆中的数据。
  • 当数据为引用类型时,且想取消变量之间的关联,需要用到深浅拷贝。
  • 当数据仅有一层时,利用...扩展运算符能很简单的实现数据的拷贝。
  • 使用JSON.parse(JSON.stringify(obj));来进行深拷贝时,应注意对象中,不能存在Date、RegExp、Function类型的数据,不然会导致数据丢失。

可以发现,当我们使用JSON.parse(JSON.stringify(obj));来进行深拷贝时,对象中不能存在Date、RegExp、Function类型的数据。但实际应用中,不可避免的会出现类似情况。此时应该怎么处理呢?

这也是面试常问问题。

1、使用Lodash JS工具库

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。其中封装了 array、number、objects、string 等等类型的数据处理方法。
我们可以通过Lodash的cloneDeep(value)方法来实现对象的深拷贝。
官网地址:https://www.lodashjs.com/docs/lodash.cloneDeep

2、手写递归实现深拷贝

我的实现思路如下:
1、 通过递归实现深拷贝
2、 通过typeof 操作符判断数据类型(typeof 不是函数,是一元操作符)
3、 当数据类型为基本类型的时候和function,直接赋值
4、 当数据类型为Object,且为数组和对象的时候,进行递归
5、 利用for in 遍历数组和对象
6、 利用hasOwnProperty判断是否需要拷贝原型上的属性
7、 利用constructor判断数据类型。
8、 利用constructor返回对创建此对象的数组函数的引用的特性,通过new 实现对Date、RegExp的深拷贝。

  function deepCopy(srouceData, onlyOwnProperty = true) {
    let resultData;
    if (typeof (srouceData) !== 'object') {
      return srouceData;
    } else {
      if (srouceData.constructor === Array || srouceData.constructor === Object) {
        resultData = new srouceData.constructor();
        for (let key in srouceData) {
          // 如果有需求,要过滤掉srouceData原型上的属性
          if (onlyOwnProperty) {
            if (Object.prototype.hasOwnProperty.call(srouceData, key)) {
              resultData[key] = deep(srouceData[key])
            }
          } else {
            resultData[key] = deep(srouceData[key])
          }
        }
      } else {
        return new srouceData.constructor(srouceData);
      }
    }
    return resultData;
  }

我们拿一个代码试试:

let srouceObj = {
  a: 'a',
  b: { b1: 'b1', bt: new Date('2020-11-1') },
  c: [1, 2, 3],
  d: new Date(),
  e: new RegExp("[a-c]", "i"),
  f: function a() {
    alert('a')
  }
}
let copyObj = this.deepCopy(srouceObj);
copyObj.b.b1 = 'b2';
copyObj.d.setFullYear(2016);
console.log(srouceObj)
// {
//  a: "a", 
//  b: { b1: 'b1', bt: Sun Nov 01 2020 00:00:00 GMT+0800 (中国标准时间) }, 
//  c: [1, 2, 3],
//  d: Wed Feb 24 2021 12:13:53 GMT+0800 (中国标准时间), 
//  e: /[a-c]/i,
//  f: f a()
//}
console.log(copyObj)
// {
//  a: "a", 
//  b: { b1: 'b2', bt: Sun Nov 01 2020 00:00:00 GMT+0800 (中国标准时间) }, 
//  c: [1, 2, 3],
//  d: Wed Feb 24 2016 12:13:53 GMT+0800 (中国标准时间), 
//  e: /[a-c]/i,
//  f: f a()
//}

拷贝成功。

相关文章

  • 手动实现深拷贝

    手动实现深拷贝

  • 【03】手动实现深拷贝

    在上文中,已经提到了深浅拷贝的概念,以及常用的深浅拷贝的方法。这里进行一个简单的回顾: 改变了一个变量的值,其他变...

  • iOS基础知识点(网络摘抄)

    1.父类实现深拷贝时,子类如何实现深拷贝。父类没有实现深拷贝时,子类如何实现深拷贝? 深拷贝同浅拷贝的区别:...

  • Java深拷贝和浅拷贝

    目录介绍 01.对象拷贝有哪些 02.理解浅拷贝2.1 什么是浅拷贝2.2 实现浅拷贝案例 03.理解深拷贝3.1...

  • iOS 容器的深浅拷贝

    很形象,我们所调用的copy,mutablecopy都是浅拷贝,如果要实现深拷贝必须,手动向容器中转入新的元素

  • 深拷贝、浅拷贝

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

  • 面试题整理

    父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 深拷贝同浅拷贝的区别:浅拷贝...

  • iOS面试基础一

    #父类实现深拷贝时,子类如何实现深度拷贝.父类没有实现深拷贝时,子类如何实现深度拷贝.# <(1)深拷贝同浅拷贝的...

  • 0. iOS面试题基础篇

    1. 父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 1.1 深拷贝同浅拷贝...

  • iOS基础知识点01

    1. 父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 1.1 深拷贝同浅拷贝...

网友评论

      本文标题:【03】手动实现深拷贝

      本文链接:https://www.haomeiwen.com/subject/nxfsfltx.html