步骤一:实现简单的递归克隆
function deepCopy(source) {
return (function _copy(parent) {
var child;
for (var i in parent) {
if (parent.hasOwnProperty(i)) {
child[i] = _copy(parent[i]);
} else {
child = parent;
}
}
return child;
})(source)
}
存在的问题
- 未处理Array,Date,Function等特殊对象
- 复制的对象的
constructor都是指向Object构造函数 - 存在循环引用问题
步骤二:处理特殊对象及constructor指向问题
function getType(obj) {
var typeString = Object.prototype.toString.call(obj);
return typeString.substring(8, typeString.length - 1);
}
function deepCopy(source) {
return (function _copy(parent) {
var child;
switch (getType(parent)) {
case 'Object':
// 处理对象原型,指向父类的constructor
child = Object.create(Object.getPrototypeOf(parent));
for (var i in parent) {
if (parent.hasOwnProperty(i)) {
child[i] = _copy(parent[i]);
}
}
break;
default:
child = parent;
}
return child;
})(source)
}
存在的问题
- 存在循环引用问题
步骤三:处理循环引用问题
function getType(obj) {
var typeString = Object.prototype.toString.call(obj);
return typeString.substring(8, typeString.length - 1);
}
function deepCopy(source) {
var copyedList = [];
return (function _copy(parent) {
var child;
switch (getType(parent)) {
case 'Object':
// 是否已经克隆过了
var isCopyIndex = copyedList.indexOf(parent);
if (isCopyIndex >= 0) {
child = copyedList[isCopyIndex]
} else {
copyedList.push(parent);
// 处理对象原型,指向父类的constructor
child = Object.create(Object.getPrototypeOf(parent));
for (var i in parent) {
if (parent.hasOwnProperty(i)) {
child[i] = _copy(parent[i]);
}
}
}
break;
default:
child = parent;
}
return child;
})(source)
}
结束语
其实还是有一些问题
- 存在爆栈的问题
- 边界问题未处理