JSON
源码:
JSON.parse(JSON.stringify())
缺点:
- 1、对象的循环引用的拷贝直接报错,不能拷贝
- 2、对象方法直接抛弃,拷贝函数返回undefined 详见链接:www.jianshu.com/p/b084dfaad…
深度优先拷贝
源码:
function DFdeepClone(obj, originObjs = [], cloneObjs = []){
let _obj = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {};
if (Object.prototype.toString.call(obj) === '[object Object]'
|| Object.prototype.toString.call(obj) ==='[object Array]'){
let index = originObjs.indexOf(obj);
if (~index){
_obj = cloneObjs[index];
} else {
originObjs.push(obj);
cloneObjs.push(_obj);
for(let item in obj){
_obj[item] = DFdeepClone(obj[item], originObjs, cloneObjs);
}
}
} else if (Object.prototype.toString.call(obj) === '[object Function]' ) {
_obj = eval("("+ obj.toString() +")");
} else {
_obj = obj;
}
return _obj;
}
优点
- 1、相对于JSON序列化,能拷贝方法,能拷贝循环引用数据
缺点
- 1、数据太长会栈溢出
广度优先拷贝
源码:
function BFdeepClone(obj){
// 返回的拷贝对象
let copyObj = {};
// 循环数据的队列,用来检测是否有循环引用数据
let visitedOriginQuene = [];
let visitedCopyQuene = [];
// 广度优先必须的遍历序列
let originQuene = [obj];
let copyQuene = [copyObj];
while (originQuene.length !== 0) {
let itemObj = originQuene.shift();
let _copyObj = copyQuene.shift();
let itemType = Object.prototype.toString.call(itemObj);
visitedOriginQuene.push(itemObj);
visitedCopyQuene.push(_copyObj);
if (itemType === '[object Object]'
|| itemType === '[object Array]'){
for (let objKey in itemObj) {
let objVal = itemObj[objKey];
let valType = Object.prototype.toString.call(objVal);
if(valType === '[object Object]'
|| valType === '[object Array]'){
let index = visitedOriginQuene.indexOf(objVal);
if (index === -1){
_copyObj[objKey] = valType === '[object Array]'?[]:{};
originQuene.push(itemObj[objKey]);
copyQuene.push(_copyObj[objKey]);
} else {
_copyObj[objKey] = visitedCopyQuene[index];
}
} else if (valType === '[object Function]') {
_copyObj[objKey] = eval("("+objVal.toString()+")");
} else {
_copyObj[objKey] = objVal;
}
}
} else if (itemType === '[object Function]') {
copyObj = eval("("+itemObj.toString()+")");
} else {
copyObj = itemObj;
}
}
return copyObj;
}
优点
- 1、能拷贝方法,能拷贝循环引用数据
缺点
- 1、牺牲了较大的时间复杂度和空间复杂度
结语
方法拷贝进控制台直接运行,有问题,还请斧正!