如何手写出一个满分的深拷贝惊艳全场?

本文介绍了深拷贝的概念及其重要性,通过解析JSON.stringify方法的局限性引入话题。接着讲解了两种JavaScript中判断对象类型的技巧,并分析了一般深拷贝实现的不足,如处理null、Date和RegExp对象的问题以及循环引用和栈溢出。为解决这些问题,文章提出了使用Map和WeakMap来处理循环引用,避免内存浪费,以及用循环替代递归以防止堆溢出。最后,给出了一个完善的深拷贝实现代码。
摘要由CSDN通过智能技术生成

深拷贝,就是开辟一个空间,并且进行赋值,而不是把引用地址进行赋值(浅拷贝)

方法1
JSON.parse(JSON.stringify(obj))

但是是有缺点的,直接贴代码,详情见注释:

			let a = {
   
				b: [],//数组
				c: {
   },//对象
				d: 1, //基本类型
				e: null,//typeof null === 'object'
				f: undefined,//类型为undefined
				g: function(){
   
					console.log('函数')
				},
				h: new Date()
			}
			// 使用JSON.parse的方式来进行深拷贝
			// 但是还是有不足的地方,比如会自动忽略undefined和函数
			// 而且对Date类型也不是很友好,会转化成字符串,是date格式的意义
			// 并且对于继承的类型没办法进行克隆
			// function Person(){}
			// Person.prototype.name = 'zaw'
			// let p = new Person()
			
			const cloneObj = JSON.parse(JSON.stringify(p))
			console.log(cloneObj,p)

无法克隆继承来的属性,结果如下:
在这里插入图片描述

知识点1:
在判断js中的类型的时候,有typeof,custryctor,instanceof,Object.prototype.toString(),四种方法。其中最完美的方法是,Object.prototype.toString.call(obj)方法,解释如下:
所有内置对象的[[Class]]属性的值是由本规范定义的.所有宿主对象的[[Class]]属性的值可以是任意值,甚至可以是内置对象使用过的[[Class]]属性的值.[[Class]]属性的值可以用来判断一个原生对象属于哪种内置类型.需要注意的是,除了通过Object.prototype.toString方法之外,本规范没有提供任何其他方式来让程序访问该属性的值(查看 15.2.4.2).

也就是说,把Object.prototype.toString方法返回的字符串,去掉前面固定的"[object “和后面固定的”]",就是内部属性[[class]]的值,也就达到了判断对象类型的目的.jQuery中的工具方法$.type(),就是干这个的.

在ES3中,规范文档并没有总结出[[class]]内部属性一共有几种,不过我们可以自己统计一下,原生对象的[[class]]内部属性的值一共有10种.分别是:“Array”, “Boolean”, “Date”, “Error”, “Function”, “Math”, “Number”, “Object”, “RegExp”, “String”.

知识点2:
再来介绍一种判断空的方法,基本类型直接判空,对象{},数组,可以时候用JSON.stringify(obj) === ‘{}’ || JSON.stringify(obj) === ‘[]’

我们来写一个一般人写的深拷贝:

			let a = {
   
				b: [],//数组
				c: {
   },//对象
				d: 1, //基本类型
				e: null,//typeof null === 'object'
				f: undefined,//类型为undefined
				g: function(){
   
					console.log('函数')
				},
				h: new Date()
			}
			// 所以我们需要考虑我们的递归的方法
			function deepClone(target){
   
				// 分类型,基本,null,undefined,array,object,函数
				if(Array.isArray(target)){
   
					let result = []
					for( let item of target){
   
						item.push(deepClone(item))
					}
					return result
				}else if
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值