对obj1进行复制,拷贝
var obj1={
a:1,
b:[1,2,3,4,5],
c:function () {
},
_d:0,
set d(value){
this._d=value;
},
get d(){
return this._d;
},
e:{
a:1,
// b:new Date(),
c:function () {
},
_d:0,
set d(value){
this._d=value;
},
get d(){
return this._d;
},
e:{
a:1,
b:2,
c:function () {
},
_d:0,
set d(value){
this._d=value;
},
get d(){
return this._d;
}
}
}
};
/*
* 浅拷贝1,只复制一层,即对象有变量的那一层,如果对象下的属性也是对象,只有引用关系
* 而没有复制,改变obj2的e下面d的值,obj1的e的值也会改变,
* 这样子不利于引用、继承等。
* */
下面的两种都是浅拷贝。
var obj2={}
for(var key in obj1){
obj2[key] = obj1[key]
}
obj2.e.b=3
console.log(obj2,obj1)
console.log(obj2.e===obj1.e)
console.log(obj2.a===obj1.a)
var obj2 = {}
obj2 = Object.assign(obj1)
obj2.e.b=3
console.log(obj2,obj1)
console.log(obj2.e===obj1.e)
console.log(obj2.e === obj1.e)
/*
* 有些时候我们需要深复制,复制对象下的对象
* 这个时候我们需要用到递归,这样,深复制后修改复制后属性对象值,就不会发生原对象改变的现象了。
*
* */
var obj2 = {}
function deepClone1(paste,cope){
var cope = cope || {}
for(var key in paste){
if(typeof paste[key] === "object"){
cope[key] = (paste[key].constructor===Array ? [] :{})
deepClone1(paste[key],cope[key])
}else{
cope[key] = paste[key]
}
}
return cope
}
obj2 = deepClone1(obj1)
console.log(obj2)
obj2.e.b=3
console.log(obj2,obj1)
console.log(obj2.e===obj1.e)//false
console.log(obj2.e === obj1.e)//false
/*
* 深拷贝2,
*有些时候我们不仅需要深复制对象的属性方法,还需要复制对象属性的get,set方法,属性的描述
* 这个时候我们需要用到defineProperty,getOwnPropertyNames getOwnPropertyDescriptor
* */
function deepClone2(sourceObj,targetObj) {
var targetObj = targetObj || {}
var names=Object.getOwnPropertyNames(sourceObj)
for(var i=0;i<names.length;i++){
var desc = Object.getOwnPropertyDescriptor(sourceObj,names[i])
if(typeof desc.value=== "object" && desc.value!==null){
var obj=new desc.value.constructor
deepClone2(desc.value,obj)
//把obj当成引用对象带入递归函数继续给obj赋值
Object.defineProperty(targetObj,names[i],{
enumerable:desc.enumerable,
writable:desc.writable,
configurable:desc.configurable,
value:obj
})
continue
}
Object.defineProperty(targetObj,names[i],desc)
}
return targetObj
}
var obj2 = deepClone2(obj1)
console.log(obj2)
obj2.e.b=3
console.log(obj2,obj1)
console.log(obj2.e===obj1.e)//false
console.log(obj2.e === obj1.e)//false