这里用递归的思想进行JS对象的深度拷贝,并进行封装,思路如下
判断是不是原始值 使用方法:typeof()/object
判断是数组还是对象 使用方法: instanceof toString constructor
建立相应的数组或对象
循环递归
function deepClone(origin,target){
var target = target || {},
toStr = Object.prototype.toString,
arr = "[object Array]";
for(var prop in origin){
if(origin.hasOwnProperty(prop)){ //选择自己的属性
if(origin[prop] !== 'null' && typeof(origin[prop]) == 'object'){//区分原始值和引用值
if(toStr.call(origin[prop]) == arr){//区分数组和对象
target[prop] = [];//建立数组
}else{
target[prop] = {};//建立对象
}
deepClone(origin[prop],target[prop]); //循环递归
}else{
target[prop] = origin[prop];
}
}
}
return target;
}复制代码
代码可以将中间target[prop]赋值操作用三目运算符简化如下:
target[prop] = (toStr.call(origin[prop]) == arr) ? [] : {};
因此 简化后的深度拷贝的代码最后如下:
function deepClone(origin,target){
var target = target || {},//容错
toStr = Object.prototype.toString,//.call
arr = "[object Array]";//数组原型
for(var prop in origin){
if(origin.hasOwnProperty(prop)){//判断是否是自己的属性
if(origin[prop] !== 'null' && typeof(origin[prop]) == 'object'){//判断引用值还是原始值
target[prop] = (toStr.call(origin[prop]) == arr) ? [] : {};//判断是数组还是对象 然后相应建立数组/对象
deepClone(origin[prop], target[prop]);//循环递归
}else{//原始值
target[prop] = origin[prop];
}
}
}
return target;
}复制代码
最后,我们可以创建两个对象来进行深度拷贝
var obj1 = {
name : 'sunny',
age : 100,
sayName : function(){
console.log(this.name);
}
}
var obj2 = {};复制代码
执行拷贝
deepClone(obj1, obj2);//放入源对象和拷贝对象复制代码