Object.keys , for in 循环遍历的时候不能包含 Symbol 属性(ES6 解构运算符可以)
- 各种类型的处理
- 循环引用
let keys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
// 浅克隆
function shallowClone(obj) {
let type = _.toType(obj);
Ctor = obj.constructor;
// 对于SymFol/BigInt,直接用Object包裹一下
if (/^(symbol|bigint)$/i.test(type)) return Object(obj);
//对于正则/日期的处理
if (/^(regexp|date)$/i.test(type)) return new Ctor(obj);
//对于错误对象的处理
if (/^error$/i.test(type)) return new Ctor(obj.message);
// 对于函数
if (/^function$/i.test(type)) {
return function () {
return obj.call(this, ...arguments);
};
}
//数组或者对象
if (/^(object|array)$/i.test(type)) {
let keys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
let newObj = new Ctor();
_.each(keys, (key) => {
newObj[key] = obj[key];
});
return newObj;
/* ES6 解构运算符可以处理Symbol属性
return type === "array" ? [...obj] : { ...obj };
*/
}
return obj;
}
// 深克隆
function deepClone(obj, cache = new Set()) {
let type = _.toType(obj);
Ctor = obj.constructor;
if (!/^(object|array)$/i.test(type)) {
return shallowClone(obj);
}
// 防止循环引用
if (cache.has(obj)) return obj;
cache.add(obj);
let keys = [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
let newObj = new Ctor();
_.each(keys, (key) => {
// 传入初始cache
newObj[key] = deepClone(obj[key], cache);
});
return newObj;
}