JS中的對象復制分為兩種情況:深拷貝和淺拷貝。
深拷貝和淺拷貝的區別在于對數組和對象的拷貝,對它們拷貝時淺拷貝只是拷貝引用地址,它們引用的是同一個數組或對象,所以對其進行修改時會互相影響;而深拷貝則是拷貝了整個的數組或對象,兩個地址指針指向的是不同的數組或對象,這樣修改互不影響。
var myObject={
a:2,
b:{c:1}
};
- 淺拷貝的實現
- Object.keys()遍歷對象屬性
對于上面這個對象myObject來說,要實現淺拷貝,可以遍歷對象中的屬性,然后將其值存入。
var keys=Object.keys(myObject);
var newObj2={};
for(var i=0;i<keys.length;i++){
newObj2[keys[i]]=myObject[keys[i]]
}
Object.keys方法可以遍歷對象中的屬性,并返回屬性名的數組,通過對數組進行遍歷,從而將其值存入新的對象中。
- ES6的Object.assign()方法
ES6中有一個方法是根據上述遍歷方法得來的,可以直接調用:assign
var newObj1 = Object.assign({},myObject);
驗證:
newObj1.a=4;
newObj2.a=3;
console.log(myObject.a,newObj1.a,newObj2.a);//2 4 3
newObj1.b.c=4;
console.log(myObject.b,newObj1.b,newObj2.b);//{ c: 4 } { c: 4 } { c: 4 }
通過更改上述對象中的a屬性的值,可以看到,對象之間互不影響,因為該值并不是對象,所以是復制的值,直接更改。但是如果更改屬性b的值,則會相互影響,因為他們引用的是同一個值。
- jQuery中的extend方法
JS中的extend()方法可以實現深拷貝和淺拷貝,通過里面的參數true,false決定。
- 深拷貝的實現
- JSON方式
先把對象轉化為JSON字符串,然后再解析成對象的形式:
var newObjDeep2=JSON.parse(JSON.stringify(myObject));
驗證:
myObject.b.c=4;
console.log(myObject,newObjDeep2);//{ a: 2, b: { c: 4 } } { a: 2, b: { c: 1 } }
- 遞歸實現
function deepCopy(obj){
var newObj;
if(typeof obj !== 'object'){
return obj;
}
if(obj instanceof Array){
newObj=[];
}else {
newObj={}
}
for(var key in obj){
if(typeof obj[key] !== "object"){
newObj[key]=obj[key];
}else{
newObj[key]=deepCopy(obj[key])
}
}
return newObj;
}
對于一個對象,先判斷其數據類型是否為數組,如果是,則寫為[]形式,不是,則為{}形式,之后再對里面的屬性名進行遍歷,判斷其屬性值是否為對象,如果是,則繼續上述操作(即遞歸),如果不是,則將其值直接復制給新對象中相應的屬性。
驗證:
var newObjDeep1=deepCopy(myObject);
myObject.b.c=4;
console.log(myObject,newObjDeep1);//{ a: 2, b: { c: 4 } } { a: 2, b: { c: 1 } }
- 上述淺拷貝中的jQuery中的extend方法