JS 物件如何實現深複製

夏茗星發表於2021-09-08

如何實現一個物件的深複製?

方法1:使用JSON (物件的序列化和反序列化)

需要注意的是:在引用資料型別中,地址是儲存在棧區的,屬性值存放在堆區的,不同的地址指向的值是不一樣的,這裡是深複製的寫法,變數地址是互不影響的,所以是obj == obj1為false,而在淺複製中就是為true的,因為在賦值的同時obj會把地址一起賦值給obj1,使他們的地址指向堆區的同一個值


// 如何實現一個物件的深複製?

//第一種方法
// 物件序列化

//建立一個物件
var obj = {
    name:'zhangsan',
    age:13
}
//因為是深複製 
//將obj序列化和反序列化後  賦值給一個obj1   
var obj1 = JSON.parse(JSON.stringify(obj));
console.log(JSON.stringify(obj), typeof JSON.stringify(obj));  //string
console.log(obj1,typeof obj1);   // { name: 'zhangsan', age: 13 }    object
console.log(obj == obj1);   //false   //因為反序列後obj1引用地址發生了改變
console.log(obj === obj1);  //false

//改變obj1中的name屬性
obj1.name = 'lisi';
//列印輸出的obj的name屬性沒有改變   
//驗證深複製只作用於棧區,棧區中變數和變數之間是獨立存在的,值得變換不會互相影響
console.log(obj,obj1);   // { name: 'zhangsan', age: 13 } { name: 'lisi', age: 13 }

方法2:第三方庫lodash 的cloneDeep

Lodash 是一個一致性、模組化、高效能的 JavaScript 實用工具庫。

要用lodash標籤庫 要先匯入lodash
在當前目錄下 終端中 執行指令 npm i --save lodash


//第二種方法
// 第三方庫lodash的cloneDeep
//lodash常用_來定義
var _ = require('lodash');
//建立一個物件
var obj = {
    name:'zhangsan',
    age:18
}
//使用cloneDeep方法   cloneDeep相當於clone,就是遞迴複製(這個我不是很明白,但是是這麼用的)
var obj2 = _.cloneDeep(obj);
//同樣是改變obj2的name屬性
obj2.age = 20;
//列印輸出obj和obj2   發現只有obj2的name屬性值改變了  原理和方法一樣
console.log(obj);  //{ name: 'zhangsan', age: 18 }

console.log(obj2);  //{ name: 'zhangsan', age: 20 }

方法3:Object.assign()實現深複製

// Object.assign(obj1,obj2); 兩個引數實現物件複製、複製 第一個引數是目標物件
let obj1 = {}
let obj2 = {
    name:'xxx',
    age:22
}
//兩個引數實現物件複製,複製   第一個引數obj1是目標物件
//把obj2中的內容複製到obj1物件當中並返回obj1物件
let res1 = Object.assign(obj1,obj2);
console.log(res1);//{ name: 'xxx', age: 22 }
console.log(obj1);//{ name: 'xxx', age: 22 }
obj1.name = '小仙女'
console.log(obj2);//{ name: 'xxx', age: 22 } //name沒有改變,證明是深複製
obj2.name = '開心超人'
console.log(obj1);  //{ name: '小仙女', age: 22 }  //沒有改變
//深複製,指向的堆區中的值不相同
console.log(obj1 === obj2); //false

方法4:使用擴充運算子... 實現深複製

// 使用擴充運算子... 實現深複製
let obj1 = {
    name: 'tom',
    age: 13
}
//用到右側是展開
let obj2 = {
    //把obj1物件拆成鍵值對
    ...obj1,
    //新增屬性
    gender: 'male'
}

console.log(obj2); //{ name: 'tom', age: 13 , gender: 'male' }
obj1.name = '瑪卡巴卡'
console.log(obj2);//{ name: 'tom', age: 13, gender: 'male' }  //沒有改變  驗證是深複製
console.log(obj1 === obj2); //false

還知道一個利用遞迴,增強版for,還有jquery中的繼承方法實現深複製,但是呢,我不會。。。。

很多種方法,待更新、、、、、、、、

分享一個偶然間看到的大佬的關於深複製與淺複製的講解部落格,總結的太好懂了,厲害厲害

https://segmentfault.com/a/11...

相關文章