深拷贝和浅拷贝
Description
深拷贝和浅拷贝是针对复杂数据类型来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。
浅拷贝
for in;
Object.assign.
...,
Array.prototype.slice(),
Array.prototype.concat()等
深拷贝
-
JSON.parse(JSON.stringify(obj,filter|[],format:"\n"), function (key, val) {return val })
- 函数无法拷贝
- 原型链上的属性无法拷贝
- 不能正确的处理 Date 类型的数据
- 不能处理 RegExp
- 会忽略 symbol undefined
-
function deepClone(target,weakMap=new WeakMap()){
if(target instanceof RegExp) return new RegExp(target);
if(target instanceof Date) return new Date(target);
if(target===null||typeof target !=='object') return target;
if(weakMap.has(target)) return weakMap.get(target);
let instance=new target.constructor();
weakMap.set(target,instance);
//包含symbol
let keys= Reflect.ownKeys(target);
// 获取源对象所有属性描述符
for(let index in keys){
let key=keys[key];
instance[key]=deepClone(target[key],weakMap);
}
//设置访问器
let descriptor = Object.getOwnPropertyDescriptors(target);
Object.defineProperties(instance,descriptor);
return instance;
}
function deepClone(target){
if(target instanceof RegExp) return new RegExp(target);
if(target instanceof Date) return new Date(target);
if(target===null||typeof target !=='object') return target;
let cloneTarget = Array.isArray(target) ? [] : {};
for (let key in target) {// 可枚举属性,包括自有属性、继承自原型的属性
cloneTarget[key] = deepClone(target[key])
}
return cloneTarget;
}
function deepClone(target,callback){
if(typeof callback!=='function'){
callback = function (key, val,target) { return val; }
}
if(target instanceof RegExp ||target instanceof Date||(target===null||typeof target !=='object') ) return callback(undefined,target);
let cloneTarget = Array.isArray(target) ? [] : {};
// forEach|keys 对象自有的可枚举属性
// getOwnPropertyNames 对象的自有属性,包括可枚举和不可枚举的
// Reflect.ownKeys (target) :Object.getOwnPropertyNames与Object.getOwnPropertySymbols之和。
for (let key in target) {// 原型属性和自身 可枚举属性
cloneTarget[key] = deepClone(callback(key,target[key],target));
}
return cloneTarget;
}