深複製與淺複製
淺複製:複製地址。舉個栗子,櫃子的第一格有一個蘋果,A手裏有一張寫着蘋果放置位置的紙條,B將A的紙條抄錄了一份,此時蘋果還是隻有一個,如果B根據紙條寫的位置去咬一口蘋果,那麼,當A再根據紙條去找到蘋果時,這個蘋果就是被咬過的蘋果。
let a={name:'張三',age:20};
//這裏的a是變量,該變量中是指向堆中{name:'張三',age:20}對象的存儲地址
let b=a; //此時b只複製了a變量中的地址,a與b指向同一個對象
console.log(a); //{name: "張三", age: 20}
console.log(b); //{name: "張三", age: 20}
console.log(a===b); //true
b.name='b修改了名字'; //通過b修改對象的name屬性
console.log(a); //{name: "b修改了名字", age: 20}
console.log(b); //{name: "b修改了名字", age: 20}
以上代碼中b只 複製 了a變量中的 地址,a與b指向 同一個對象,因此通過b修改指向對象的屬性後輸出a,b都是被修改後的對象。
深複製:複製值,即將 複製 對象的 內容 都複製過來,產生一個 新的對象。舉個栗子,用放在櫃子第一格的蘋果a克隆出一個一模一樣的蘋果b,並將蘋果b放在櫃子第二格,這兩個蘋果雖然長得一模一樣,但不能說a和b是同一個蘋果,就算咬一口蘋果b,也只有蘋果b上有牙印,蘋果a不會受到影響。
console.log({name:'張三'}==={name:'張三'}); //false
深複製的方法
1. JSON.parse(JSON.stringify(obj)) 實現深複製
JSON.stringify將對象轉換爲字符串,再通過JSON.parse將其還。
注意: 此方法僅適用於一般數據的拷貝,如對象、數組。
let person = {
name:'張三', //一級屬性
sex:'男',
friend:{
name:'李四', //二級屬性
sex:'女',
}
};
let personCopy=JSON.parse(JSON.stringify(person));
console.log(personCopy);
personCopy打印結果:
驗證是否深複製:
personCopy.name = '修改名字';
personCopy.friend.name = '修改朋友名字';
console.log(person);
console.log(personCopy);
深複製完成:
2. Object.assgin() 實現深複製
注意: Object.assgin()只能 深複製一級屬性,當二級屬性爲引用數據類型的時候就是 淺複製二級屬性
let person = {
name:'張三', //一級屬性
sex:'男',
friend:{
name:'李四', //二級屬性
sex:'女',
}
};
let newPerson = Object.assign({},person); //使用Object.assgin()將person複製給newPerson
console.log(newPerson);
newPerson打印結果:
此時,newPerson將person的一級屬性進行了深複製,二級屬性仍然只進行了淺複製,證明如下:
newPerson.name='改變一級屬性'; //newPerson改變一級屬性
newPerson.friend.name='改變二級屬性'; //newPerson改變二級屬性
console.log(person);
console.log(newPerson);
深複製一級屬性,二級屬性仍爲地址:
3. for in 遞歸實現深複製
let thisObj = {
name:'張三',
like:{
ball:'籃球',
eat:'西紅柿炒雞蛋',
}
};
//寫一個遞歸深複製的方法
function clone(obj) {
let newObj = {};
for (let key in obj){
if (typeof obj[key]==='object'){ //如果obj的該項數據類型依然爲對象
newObj[key]=clone(obj[key]); //調用自己,該項再次進入判斷、複製
}else {
newObj[key] =obj[key]
}
}
return newObj;
}
let newObj = clone(thisObj);
console.log(thisObj);
console.log(newObj);
複製後打印結果:
驗證是否深複製:
newObj.name='修改名字'; //修改一級屬性
newObj.like.ball='修改籃球'; //修改二級屬性
console.log(thisObj);
console.log(newObj);
深複製完成:
4. jquery的extend方法實現深複製
$.extend( [deep ], target, object1 [, objectN ] )
deep : 布爾值,默認爲false(不支持第一個參數傳遞false),爲true時爲深拷貝,爲false時不會深度合併對象;
target: Object類型 目標對象,其他對象的成員屬性將被附加到該對象上;
object1, objectN: Object類型 被合併的對象。
false舉例:
let newPerson = {};
$.extend(newPerson,person);
console.log(newPerson);
console.log(newPerson===person);
輸出:
驗證未深度合併:
newPerson.name='修改';
newPerson.friend.name='修改';
console.log(person);
console.log(newPerson);
true舉例:
let newPerson = {};
$.extend(true,newPerson,person);
console.log(newPerson);
console.log(newPerson===person);
輸出:
驗證深複製:
newPerson.name='修改';
newPerson.friend.name='修改';
console.log(person);
console.log(newPerson);