博客 / 詳情

返回

JS 對象如何實現深拷貝

如何實現一個對象的深拷貝?

方法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...

user avatar liyl1993 頭像 iymxpc3k 頭像 huanjinliu 頭像 b_a_r_a_n 頭像 joytime 頭像 lidalei 頭像 shengmingbuxi_5c1152527848f 頭像 caideheirenyagao 頭像 jidongdemogu 頭像 alogy 頭像 air_clou_d 頭像 shellingfordly 頭像
20 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.