深浅拷贝主要针对的是Object类型,基础类型的值本身即是复制一模一样的一份,不区分深浅拷贝。下面web建站小编给大家介绍一下代码!
代码如下:
function deepClone(target) { // WeakMap作为记录对象Hash表(用于防止循环引用) const map = new WeakMap() // 判断是否为object类型的辅助函数,减少重复代码 function isObject(target) { return (typeof target === 'object' && target ) || typeof target === 'function' } function clone(data) { // 基础类型直接返回值 if (!isObject(data)) { return data } // 日期或者正则对象则直接构造一个新的对象返回 if ([Date, RegExp].includes(data.constructor)) { return new data.constructor(data) } // 处理函数对象 if (typeof data === 'function') { return new Function('return ' + data.toString())() } // 如果该对象已存在,则直接返回该对象 const exist = map.get(data) if (exist) { return exist } // 处理Map对象 if (data instanceof Map) { const result = new Map() map.set(data, result) data.forEach((val, key) => { // 注意:map中的值为object的话也得深拷贝 if (isObject(val)) { result.set(key, clone(val)) } else { result.set(key, val) } }) return result } // 处理Set对象 if (data instanceof Set) { const result = new Set() map.set(data, result) data.forEach(val => { // 注意:set中的值为object的话也得深拷贝 if (isObject(val)) { result.add(clone(val)) } else { result.add(val) } }) return result } const keys = Reflect.ownKeys(data) const allDesc = Object.getOwnPropertyDescriptors(data) const result = Object.create(Object.getPrototypeOf(data), allDesc) // 新对象加入到map中,进行记录 map.set(data, result) // Object.create()是浅拷贝,所以要判断并递归执行深拷贝 keys.forEach(key => { const val = data[key] if (isObject(val)) { // 属性值为 对象类型 或 函数对象 的话也需要进行深拷贝 result[key] = clone(val) } else { result[key] = val } }) return result } return clone(target) } // 测试 const clonedObj = deepClone(obj) clonedObj === obj // false,返回的是一个新对象 clonedObj.arr === obj.arr // false,说明拷贝的不是引用 clonedObj.func === obj.func // false,说明function也复制了一份 clonedObj.proto // proto,可以取到原型的属性
标签: 深拷贝
上面是“什么是javascript深拷贝”的全面内容,想了解更多关于 js 内容,请继续关注web建站教程。
当前网址:https://m.ipkd.cn/webs_2528.html
声明:本站提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请发送到邮箱:admin@ipkd.cn,我们会在看到邮件的第一时间内为您处理!