【JavaScript源代码】JavaScript深拷贝的一些踩坑记录.docx
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
JavaScript深拷贝的一些踩坑记录 之前去一家公司面试的时候,面试官问了我一个问题,说:"如何才能深拷贝一个对象"。当时我心里有些窃喜,这么简单的问题还用想吗?于是脱口而出:"平时常用的有两种办法,第一种用JSON.parse(JSON.stringify(obj)),第二种可以使用for...in加递归完成"。面试官听了以后点了点头觉得挺满意的。 当时我也并没有太过在乎这个问题,直到前段时间又想起这个问题,发现上面说的两种方法都是有Bug的。 那么上面所说的Bug是什么呢? 特殊对象拷贝 首先让我们试想有这么一个对象,在不考虑普通类型的情况下,它有如下成员: const o JavaScript中的深拷贝是开发过程中常见且重要的概念,主要用于创建一个与原对象具有相同属性和值的新对象,但不会因改变原始对象而影响复制对象。然而,深拷贝并不总是那么简单,尤其在处理特殊类型的对象时,可能会遇到一些陷阱。 在JavaScript中,常见的深拷贝方法有两种:JSON.parse(JSON.stringify()) 和 递归复制。然而,这两种方法都有其局限性: 1. **JSON.parse(JSON.stringify())** 方法: - 对于对象中的函数,此方法会丢失,因为JSON不支持函数。 - 对于Date对象,它会被转换为字符串。 - 对于正则表达式(RegExp),它会被忽略,只保留空对象。 - 更严重的是,对于循环引用的对象(环),此方法会导致栈溢出错误,因为它无法处理无限递归。 2. **递归复制** 方法: - 此方法通常涉及遍历对象的每个属性并递归复制它们。尽管它可以处理更复杂的对象结构,但同样不能处理函数、Date、RegExp等特殊对象,而且如果没有正确处理循环引用,也会导致无限递归和栈溢出。 为了克服这些问题,我们需要对这些特殊对象进行特殊处理。例如,对于Date对象,我们可以创建一个新的Date实例,使用原始Date对象的时间戳来初始化。对于正则表达式,可以使用构造函数创建新的正则对象。对于函数,可能需要考虑是否需要拷贝或保留原始函数的引用,这取决于具体场景。 对于循环引用,我们可以使用`WeakMap`来存储已复制的对象,每次尝试复制对象时,先检查`WeakMap`中是否存在,如果存在则直接返回,否则继续复制过程。这样可以避免无限递归。 以下是一个改进的深拷贝函数,考虑了Date和RegExp的特殊处理,以及环的检测: ```javascript function deepCopy(obj, hash = new WeakMap()) { if(hash.has(obj)) return hash.get(obj); let cloneObj; let Constructor = obj.constructor; switch(Constructor){ case RegExp: cloneObj = new Constructor(obj); break; case Date: cloneObj = new Constructor(obj.getTime()); break; default: if(hash.has(obj)) return hash.get(obj); cloneObj = Array.isArray(obj) ? [] : {}; hash.set(obj, cloneObj); // ...继续遍历并复制其他属性 } // 遍历并复制属性 for (let key in obj) { if(obj.hasOwnProperty(key)) { cloneObj[key] = isObj(obj[key]) ? deepCopy(obj[key], hash) : obj[key]; } } return cloneObj; } function isObj(obj) { return (typeof obj === 'object' || typeof obj === 'function') && obj !== null; } ``` 这个函数将能够更好地处理包含特殊对象和循环引用的对象的深拷贝。然而,对于更复杂的情况,如自定义构造函数创建的实例,可能需要额外的逻辑来处理。在实际开发中,可以考虑使用第三方库如lodash的`_.cloneDeep`方法,以获得更全面的深拷贝功能。


剩余6页未读,继续阅读





















- 粉丝: 1w+
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源



评论0