深拷贝
JSON.stringify()
是目前开发过程中最简单的深拷贝方法 其实就是把一个对象序列化成为 JSON
的字符串,并将对象里面的内容转换成字符串,最后再用 JSON.parse()
的方法将 JSON
字符串生成一个新的对象
let q = { age: 1, jobs: { first: 'FE' } } let b = JSON.parse(JSON.stringify(q)) q.jobs.first = 'native' console.log(b.jobs.first)
1 拷贝的对象的值如果有 函数
,undefined
,symbol
这几种类型,经过 JSON.stringify() 序列后的字符串中这个键值对会消失
2 拷贝 Date引用类型
会变成字符串
3 无法拷贝不可枚举的属性
4 无法拷贝对象的原型链
5 拷贝 RegExp引用类型
会变成空对象
6 对象中含有 NaN
,Infinity
以及 -Infinity
,JSON.parse()序列化的结果会变成 null
7 无法拷贝对象的循环引用,即 对象成环(obj[key]=obj)
的情况
用递归实现 深拷贝 针对上面几个待解决问题,我们应该怎么做呢?
a. 针对能够遍历对象的不可枚举属性以及 Symbol
类型,我们可以使用 Reflect.ownKeys(可以获取一个对象的所有属性,包括可枚举属性、不可枚举属性和 Symbol 类型属性)
方法 b. 当参数为 Date、Regexp
类型,则直接生成一个新的实例返回 c. 利用 Object.getOwnPropertyDescriptors
方法可以获得对象的所有属性,以及对应的特性,顺便结合Object.create
方法创建一个新对象,并继承传入原对象的原型链 d. 利用 weakMap
类型作为 Hash
表,因为 weakMap
是弱引用类型,可以有效防止内存泄露,作为检测循环引用很有帮助,如果存在循环,则引用直接返回 weakmap
存储的值
// 判断一个对象是否为复杂数据类型,即对象或函数类型,且不为 null const isComplexDataType = obj => (typeof obj === 'object' || typeof obj === 'function') && (obj !== null) // 定义深拷贝函数 deepClone,接受两个参数:obj 为要进行深拷贝的目标对象,hash 为已经拷贝过的对象的哈希表(用于解决循环引用问题) const deepClone = function (obj, hash = new WeakMap()) { // 如果目标对象是日期对象,则直接返回一个新的日期对象,避免修改原日期对象 if (obj.constructor === Date) { return new Date(obj) } // 如果目标对象是正则对象,则直接返回一个新的正则对象,避免修改原正则对象 if (obj.constructor === RegExp){ return new RegExp(obj) } // 如果目标对象已经被拷贝过,则从 hash 中获取已经拷贝过的对象并返回,避免出现循环引用问题 if (hash.has(obj)) { return hash.get(obj) } // 获取目标对象的所有属性描述符 let allDesc = Object.getOwnPropertyDescriptors(obj) // 创建一个新对象 cloneObj,并将其原型链指向 obj 的原型对象 let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc) // 将目标对象和克隆对象的映射关系存入 hash 中,用于解决循环引用问题 hash.set(obj, cloneObj) // 遍历目标对象的所有属性(包括字符串类型和 Symbol 类型的属性名) for (let key of Reflect.ownKeys(obj)) { // 如果目标对象的属性值是复杂数据类型(即对象或数组),则递归调用 deepClone 函数进行深拷贝,并将拷贝结果赋值给克隆对象的对应属性 if (isComplexDataType(obj[key]) && typeof obj[key] !== 'function') { cloneObj[key] = deepClone(obj[key], hash) } else { // 如果目标对象的属性值不是复杂数据类型,则直接将其赋值给克隆对象的对应属性 cloneObj[key] = obj[key] } } // 返回深拷贝后的新对象 return cloneObj }
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgahgca
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01