ES5和ES6的深拷贝问题

news/2024/7/10 23:54:37 标签: es6, javascript, 开发语言

深拷贝我们知道是引用值的一个问题,因为在拷贝的时候,拷贝的是在内存中同一个引用。所以当其中的一个应用值发生改变的时候,其他的同一个引用值也会发生变化。那么针对于这种情况,我们需要进行深度拷贝,这样就可以做到引用值之间互不干扰的情况。

ES5 深拷贝

javascript">function deepClone(origin, target){
  var target = target || {},
      toStr = Object.prototype.toString,
      arrType = '[object Array]';

  for (const key in origin) {
    if (origin.hasOwnProperty.call(origin, key)) {
      if(typeof origin[key] == 'object' && origin[key] !== null){
        target[key] = toStr.call(origin[key]) === arrType ? [] : {};
        deepClone(origin[key],target[key])
      }else{
        target[key] = origin[key]
      }
    }
  }
  return target;
}

ES6深拷贝

探究ES6深拷贝的之前,我们先看一下ES6中WeakMap是什么东西?在学习ES6知识中,我们知道Map是解决对象属性只能够是字符串的形式,在ES6中Map的出现,让对象的属性可以是任何类型。而WeakMapMap的主要区别在于前者是弱引用,后者是强引用。并且WeakMap的键名只能够是对象的形式。
那什么是弱引用呢?我们这里弱引用指代的是WeakMap的键名,WeakMap它的键名所引用的对象都是弱引用,即垃圾回收机制不将该引用考虑在内,因此,只要所引用的对象的其他引用都被清除,垃圾回收机制就会释放对该对象所占用的内存。也就是说,一旦不需要,WeakMap里面的键名对象和所对应的键值对就会自动的消失,不用手动删除引用。
下面的例子中,oBtn1oBtn2作为WeakMap储存的两个对象,当外界将oBtn1oBtn2删除之后,那么由于WeakMap中的键名是弱引用的原因,所以导致WeakMap里面的键名对象和所对应的键值对就会自动的消失,不用手动的删除。这也是比较合适WeakMap的使用场景。

javascript">const oBtn1 = document.querySelector('#btn1');
const oBtn2 = document.querySelector('#btn2');

const oBtnMap = new WeakMap();

// WeakMap
oBtnMap.set(oBtn1, handleBtn1Click);
oBtnMap.set(oBtn2, handleBtn2Click);

oBtn1.addEventListener('click', oBtnMap.get(oBtn1), false);
oBtn2.addEventListener('click', oBtnMap.get(oBtn2), false);

function handleBtn1Click(){}
function handleBtn2Click(){}

// 删除节点
oBtn1.remove();
oBtn2.remove();

熟悉WeakMap之后,我们来看ES6深拷贝问题。其实ES6深拷贝面临的问题是引用的循环,我们先来看一个例子。从例子的现象来看,此时由于引用值的相互引用问题,导致test1test2相互引用,无限的引用下去。如果利用上面的ES5的深拷贝方式,那么就会抛出异常,所以我们尝试利用ES6的方式来更好的解决下面的这种问题。

javascript">const test1 = {};
const test2 = {};
test1.test2 = test2;
test2.test1 = test1;
console.log(test1);

image.png

javascript">function deepClone(origin, hashMap = new WeakMap()) {
	if (origin == null || typeof (origin) !== 'object') {
		return origin;
	}
	
	if (origin instanceof Date) {
		return new Date(origin);
	}
	
	if (origin instanceof RegExp) {
		return new RegExp(origin);
	}
	
	const hashKey = hashMap.get(origin);
	if (hashKey) {
		return hashKey;
	}
	const target = new origin.constructor();
	hashMap.set(origin, target);
	for (var key in origin) {
		if (origin.hasOwnProperty(key)) {
			target[key] = deepClone(origin[key], hashMap);
		}
	}
	return target;
}

image.png


http://www.niftyadmin.cn/n/5454907.html

相关文章

python-pytorch 常用api打卡0.1.300

python-pytorch 常用api打卡0.1.100 torch.nntorch.nn.Flattentorch.nn.Lineartorch.nn.ReLU torch.nn torch.nn.Flatten 维度计数是从0开始m nn.Flatten()默认从1维开始合并合并的维度值,就是这些维度的乘积对于数据维度的理解 如下数据input 4.1 对于数据-1.19…

深度学习中的Attention机制

深度学习中的Attention机制 一、Encoder-Decoder框架二、Attention机制(1) Soft Attention模型(2) Attention机制的本质思想(3) Self Attention模型(4) Attention机制的应用 一、Encoder-Decoder框架 Encoder-Decoder框架是一种深度学习领域的研究模式,应用场景异常…

最优算法100例之09-数组中单独出现两次的数字

专栏主页:计算机专业基础知识总结(适用于期末复习考研刷题求职面试)系列文章https://blog.csdn.net/seeker1994/category_12585732.html 题目描述 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 题解报告 最优解…

LanguageMPC:将大模型作为自动驾驶的决策者(一)

欢迎大家关注我的B站: 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 目录 1.引入LLM的背景 2.文章架构 3.国内外研究现状

信号处理--情绪分类数据集DEAP预处理(python版)

关于 DEAP数据集是一个常用的情绪分类公共数据,在日常研究中经常被使用到。如何合理地预处理DEAP数据集,对于后端任务的成功与否,非常重要。本文主要介绍DEAP数据集的预处理流程。 工具 图片来源:DEAP: A Dataset for Emotion A…

【C语言】Infiniband驱动init_dev_assign函数

一、注释 一个内核模块的初始化函数,用于分配和初始化某些资源。以下是对代码块的逐行中文注释: // 定义一个初始化设备分配的函数 static void init_dev_assign(void) {int i 1;spin_lock_init(&dev_num_str_lock); // 初始化自旋锁if (mlx4_fil…

[AIGC] 对比MySQL全文索引,RedisSearch,和Elasticsearch的详细区别

全文搜索是数据库和搜索引擎的重要功能。这个功能能在一个或多个列中查找用户查询的文本,这对诸如电子商务网站和检索大量文本数据的应用是必需的。在这篇文章中,我们将详细对比三种主流全文搜索技术: MySQL全文索引,Redis的Redis…

python学习13:python中的字符串格式化

python中的字符串格式化另外一种方式 我们前面是使用的%d,%f,%s占位符来实现字符串的格式化的;这次我们通过f"{}"来快速实现格式化,代码示例如下: