总体思想:1.判断传入参数obj是否属于object对象,不是则返回原值。
2.判断obj属于object对象后,有三种特殊情况,日期和正则和null,日期和正则返回用obj创建的新特殊对象就好,null返回null
3.使用obj的构造器创建新对象newobj,这一步是为了继承原型链
4.接下来为newobj赋值obj的key和对应的值。用for in遍历obj的属性名,因为for in会将原型链上的属性名也列出来,所以要用obj.hasOwnProperty(key)来判断是否是对象独有的属性。用val接收key对应的值,为新对象newobj添加属性key和对应的值val。如果val不是object,则直接赋值,如果是,则将val作为参数递归,直到最里面的属性也被赋值给newobj,最后返回newobj即可
function deepcopy(obj){
if(typeof obj!=='object')return obj //排除obj不是object的情况
if(obj===null)return null //排除obj是null的情况。
//下面是两种object的特殊情况,日期和正则,返回用obj创建的新对象就好了
if(obj.constructor===Date){return new Date(obj)};
if(obj.constructor===RegExp){return new RegExp(obj)};
var newobj=new obj.constructor() //继承原型链
for(key in obj){ //遍历obj的属性名
if(obj.hasOwnProperty(key)){ //判断是否是obj自己的属性名,而非原型链的
var val=obj[key]; //利用val接收obj key的值
//为newobj添加key属性并赋值,如果值不为对象,则直接赋值,如果为对象则递归。递归返回的会是一个对象,这样就完成了深拷贝
newobj[key]=typeof val=='object'?arguments.callee(val):val;
}
}
return newobj
}
var obj1={a:"b",c:{d:"e"}}
deepcopy(obj1)
先经过上面四个判断,很显然都不是,然后继承原型链。
newobj["a"]="b"
newobj["c"]=deepcopy({d:"e"})
deepcopy({d:"e"})
先经过上面四个判断,很显然都不是,然后继承原型链。
newobj[d]="e"
返回newobj 此时newobj={d:"e"}
newobj["c"]={d:"e"}
newobj={a:"b",c:{d:"e"}}