【筆記】深複製與淺複製

深複製與淺複製

淺複製:複製地址。舉個栗子,櫃子的第一格有一個蘋果,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打印結果:
console.log(personCopy)的輸出
驗證是否深複製:

personCopy.name = '修改名字';
personCopy.friend.name = '修改朋友名字';
    
console.log(person);
console.log(personCopy);

深複製完成:
修改屬性值後person與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輸出
此時,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類型 目標對象,其他對象的成員屬性將被附加到該對象上;
object1objectN: 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);

驗證深複製

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章