深拷贝&浅拷贝解析,从原理理解深拷贝

这块应该都有过比较深刻的了解了。今天加深下印象和查漏补缺下。

浅拷贝:

let original = { a: 1, b: { c: 2 } };//这边定一个obj,来供拷贝

let shallowCopy = Object.assign({}, original);// let shallowCopy = { ...original };

创建一个浅拷贝对象拷贝原来的对象

shallowCopy.b.c = 3;

修改对象中的深处项

console.log(original); // 输出:{ a: 1, b: { c: 3 } }

console.log(shallowCopy); // 输出:{ a: 1, b: { c: 3 } }

可以发现原来的对象和你所拷贝的对象的值会一起变化

深拷贝:

// 使用JSON方法(有局限性)
let original = { a: 1, b: { c: 2 } };
let deepCopy = JSON.parse(JSON.stringify(original));

deepCopy.b.c = 3;
console.log(original);      // 输出:{ a: 1, b: { c: 2 } }
console.log(deepCopy);      // 输出:{ a: 1, b: { c: 3 } }

也可以使用load库的

// 使用lodash库(需要先安装lodash)

// const _ = require('lodash');

// let deepCopy = _.cloneDeep(original);

可以发现原先的对象不会随着你所拷贝对象的变化而变化

手写一个深拷贝

//   深拷贝

function deepClone(obj, cache = new WeakMap()) {

  if (typeof obj !== 'object') return obj

  if (obj === null) return obj

  if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环

  if (obj instanceof Date) return new Date(obj)

  if (obj instanceof RegExp) return new RegExp(obj)

  // 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数

  let cloneObj = new obj.constructor()

  cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况

  for (let key in obj) {

    if (obj.hasOwnProperty(key)) {

      cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝

    }

  }

  return cloneObj

}

const obj = { name: 'Jack', address: { x: 100, y: 200 } }

obj.a = obj // 循环引用

const newObj = deepClone(obj)

console.log(newObj.address === obj.address) // false

初步解析:

1.首先判断类型,基本类型,直接返回

2.复杂对象判断,处理null的逻辑

3.防止函数陷入无限引用

4.处理日期和正则表达式

这边用一个复杂对象来更好的帮助理解

const complexObj = {
  number: 123,
  string: 'Hello',
  date: new Date(),
  regex: /abc/gi,
  array: [1, 2, 3],
  nested: {
    boolean: true,
    nullValue: null,
    undef: undefined,
    nestedObj: {
      a: 1,
      b: [2, 3]
    }
  },
  circular: null // 将会在稍后设置循环引用
};

首先他一定是个对象,不是null date 正则什么的~

这边直接看到循环函数

  for (let key in obj) {

    if (obj.hasOwnProperty(key)) {

      cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝

    }

  }

其中hasOwnProperty是检查obj是否直接拥有该key,而不是从原型链继承下来的

返回用deepClone进行深拷贝,会进行cloneObj[number]的赋值,即deepClone()

比如例子的object的第一个key为[number],会进行cloneObj[key]的赋值=deepClone(obj[number],cache),其中obj[number]的值为123,!==objecet,会return 123

就可以cloneObj得到{number:123}

再遍历下一个key string,同理,直到key为nested的时候,检测到为object。会重复上边的势力,实现一个新的一模一样的实例

相关推荐

  1. 拷贝&拷贝解析原理理解拷贝

    2024-06-10 14:30:04       5 阅读
  2. 拷贝拷贝

    2024-06-10 14:30:04       13 阅读
  3. 拷贝拷贝

    2024-06-10 14:30:04       12 阅读
  4. 拷贝拷贝

    2024-06-10 14:30:04       5 阅读
  5. 拷贝拷贝

    2024-06-10 14:30:04       0 阅读
  6. c++拷贝拷贝

    2024-06-10 14:30:04       0 阅读
  7. 拷贝拷贝全面解析及实战

    2024-06-10 14:30:04       3 阅读

最近更新

  1. 常用的设计模式

    2024-06-10 14:30:04       0 阅读
  2. 服务器添加TLS域名证书核子之PKCS编解码

    2024-06-10 14:30:04       0 阅读
  3. WDF驱动开发-I/O请求的处理(四)

    2024-06-10 14:30:04       0 阅读
  4. Flask-RQ

    2024-06-10 14:30:04       0 阅读
  5. 《 Python趣味编程 | 从入门到就业》专栏介绍

    2024-06-10 14:30:04       0 阅读
  6. SpaTracker&CoTracker 环境配置

    2024-06-10 14:30:04       0 阅读
  7. oracle中使用临时表GLOBAL TEMPORARY TABLE

    2024-06-10 14:30:04       0 阅读
  8. python调用SDK的问题

    2024-06-10 14:30:04       0 阅读
  9. Python笔记 - 正则表达式

    2024-06-10 14:30:04       0 阅读
  10. 搭建Conda虚拟环境让python程序脚本更干净

    2024-06-10 14:30:04       0 阅读

热门阅读

  1. 不要使用业务键作为数据库主键

    2024-06-10 14:30:04       6 阅读
  2. 爬山算法的详细介绍

    2024-06-10 14:30:04       5 阅读
  3. SSRF 漏洞实践:端口扫描与任意文件读取

    2024-06-10 14:30:04       3 阅读
  4. SpringBoot实现上传头像(查看头像)

    2024-06-10 14:30:04       4 阅读
  5. 模拟CAS算法案例

    2024-06-10 14:30:04       4 阅读
  6. DeepSpeed Autotuning

    2024-06-10 14:30:04       2 阅读
  7. 10-Eureka-服务注册

    2024-06-10 14:30:04       3 阅读
  8. 在docker容器中使用gdb调试python3.11的进程

    2024-06-10 14:30:04       3 阅读