javaScript终极版-深拷贝
2021-03-13 04:35
标签:function 数据结构 types ups == ssi key 集合 lse
-------------人工分割线------------- 浅拷贝这里不做介绍了,深拷贝的实现要点,除了一定要深!还要能兼容各种类型,如函数,正则、Date等等。 但上班拧螺丝,面试造航母的精神不容小觑!本着专研精神去看待怎么才能写个牛逼、各种场合都能通用的克隆方式?我做了不少功课。 在思考如何实现深拷贝之前,首先得弄明白: 待克隆对象 核心代码 代码注释感觉都写的很清楚了。写完这篇文章就可以安心的来一把无限火力了。 测试过挺多数据结构的都完美通过。如果有发现问题的同学帮忙指出来。感激不尽 javaScript终极版-深拷贝 标签:function 数据结构 types ups == ssi key 集合 lse 原文地址:https://www.cnblogs.com/bigname/p/14062427.html
其实日常业务开发中,Json.parse(Json.stringfy(obj))已经能够解决90%左右的克隆需求。还有Object.assign() Object.create()都能满足一定的克隆需求。
实现思路:
直接上代码:
let obj = {
newDate: new Date(‘2020-10-11 12:00:01‘),
null: null,
string: ‘string‘,
num: 23,
nan: NaN,
func: function () {console.log(‘function‘)},
arr: [1,2,3],
reg: /ABC\-001/,
regObj: new RegExp(/ABC/),
object: {
c: {
a: 1
}
},
};
obj.loop = obj; // 循环引用
let sup = {
name: ‘super‘,
show: function () {
console.log(‘show‘)
}
}
let objectSup = {
objectSupName: ‘objectSupName‘,
objectSupShow: function () {
console.log(‘objectSupShow‘)
}
}
Object.setPrototypeOf(obj, sup); // 根对象设置原型对象
Object.setPrototypeOf(obj.object, objectSup); // 子对象设置原型对象
// 使用WeakMap是便于回收
function deepClone(obj, cacheCurr = new WeakMap()) {
// 如果该对象已经创建好,则从缓存中获取直接返回
if (cacheCurr.has(obj)) return cacheCurr.get(obj);
// 通用的类型集合,方便后面统一处理:new obj.constructor(obj),所以该集合一定是要能够这样创建的才能放进来
const types = [‘RegExp‘, ‘Date‘, ‘Set‘, ‘Map‘, ‘WeakMap‘, ‘WeakSet‘];
// 获取当前对象类型
let objDataType = Object.prototype.toString.call(obj).slice(8, -1);
// 对比当前类型是否在通用类型中,在则统一处理克隆。【较通用的处理方式】
if(types.includes(objDataType)) return new obj.constructor(obj);
// 创建克隆对象
let cloneObj = objDataType === ‘Array‘ ? [] : {};
// 继承原型
if(obj) Object.setPrototypeOf(cloneObj,Object.getPrototypeOf(obj));
// 普通引用类型及非引用类型克隆,Reflect.ownKeys能够获取自身所有属性【非枚举也可】
for(let key of Reflect.ownKeys(obj)) {
let value = obj[key];
let valueType = Object.prototype.toString.call(value).slice(8, -1);
// 引用类型处理
if(valueType === ‘Object‘ || valueType === ‘Array‘ || types.includes(valueType)) {
// 对引用类型进行递归进入当前级的下一级进行遍历
cloneObj[key] = deepClone(value, cacheCurr);
// 记录已创建引用
cacheCurr.set(obj, cloneObj);
} else { // 非引用类型处理
cloneObj[key] = value;
}
}
return cloneObj;
}
上一篇:LeetCode刷题-04-排序
下一篇:前端使用 ajax 访问后端 django 程序 报错误: POST http://127.0.0.1:8001/xxx 403 (Forbidden)