实现浅克隆 代码如下
toType 方法
function toType(target) {
let type = typeof target;
if(type == 'object') {
let obj = {},
toString = obj.toString;
type = ((toString.call(target)).slice(8, -1)).toLocaleLowerCase();
}
return type;
}
浅克隆 方法
function shallowClone(target) {
const type = toType(target),
Ctor = target.constructor;
// 如果是Symbol 跟 bagInt 处理方式
if(/^(symbol|bigInt)$/i.test(type)) return Object(type);
// 这个是处理时间跟正则
if(/^(date|regexp)$/i.test(type)) return new Ctor(type);
// 这个是处理 函数的部分
if(/^(function)$/i.test(type)) {
// 返回一个新的函数给它 然后执行以前老函数的方法 相当于克隆了一遍
return function() {
target.call(this, ...arguments);
}
};
// 这个是错误类型的处理
if(/^(error)$/i.test(type)) return new Ctor(target.message);
// 这个是处理对象跟数组的部分
if(/^(object|array)$/i.test(type)) {
// 通过Object.keys 去拿到他所有的key 属性,但是 Object.keys 有一个缺点就是 拿不到Sysbol作为key的属性
// 所以我们要 拿到所有的keys 就应该这么写
const keys = [...Object.keys(target), ...Object.getOwnPropertySymbols(target)],
result = new Ctor(); // 这句话的意思是 如果他是对象就创建一个{} 如果是数组就创建一个[]
keys.forEach((key)=>{
result[key] = target[key];
});
// 最后把结果给输出出来
return result;
};
// 如果是基本类型 就直接返回
return target;
}
深克隆方法
function deepClone(target, cache = new Set) {
const type = toType(target),
Ctor = target.constructor;
// 这里判断一下 如果不是引用类型就浅克隆一下
if(!/^(object|array)$/i.test(type)) return shallowClone(target);
// 这里是 防止循环引用 无线套娃的情况
if(cache.has(target)) return target;
cache.add(target);
// 如果是数组 那么就下面的处理
const keys = [...Object.keys(target), ...Object.getOwnPropertySymbols(target)],
result = new Ctor(); // 这句话的意思是 如果他是对象就创建一个{} 如果是数组就创建一个[]
keys.forEach((key)=>{
result[key] = deepClone(target[key], cache);
});
return result;
}
const arr = {
“a”: 5,
“b”: [1,5,2],
“c”: {
“cc”: 111
},
“tag”: Symbol(“tag”)
};
const arr1 =deepClone(arr);
这里加入 cache是防止 循环引用 例如
const arr = {
"a": 5,
"b": [1,5,2],
"c": {
"cc": 111
},
"tag": Symbol("tag"),
// 防止一直循环套娃
"xxx": arr
};