標籤:sar rop 就是 實現 圖片 inf parse 基本 控制台
一、初步區分深拷貝與淺拷貝
JS中有深拷貝與淺拷貝之說。什麼是深拷貝什麼是淺拷貝,簡單點來說:就是假設B複製了A,當修改A時,看B是否變化。如果B也跟著變化,就是淺拷貝。如果B沒有變,就是深拷貝。
二、深入瞭解
JS中有基礎資料型別 (Elementary Data Type)與引用資料類型。
資料類型:number,string, boolean, null, undefined 五類。
引用資料類型(object類),無序對象,數組[1,2,3]以及函數等。
1、基礎資料型別 (Elementary Data Type) -- 可以算是深拷貝(名和值都存在棧記憶體中)
let a=1
當b=a複製時,棧記憶體中會新開闢一個記憶體:
所以當你此時修改a=2,對b並不會造成影響,可以說是深拷貝,但並非嚴格意義上的深拷貝。
2、引用資料類型(名存在棧記憶體中,值存在於堆記憶體中,但是棧記憶體會提供一個引用的地址指向堆記憶體中的值)
let a= [0,1,2,3,4]
當b=a進行拷貝時,其實複製的是a的引用地址,而並非堆裡面的值。
而當a[0]=1時進行資料修改時,由於a和吧指向的是同一個地址,所以b也受到了影響,這就是淺拷貝。
三、如何?將淺拷貝變成深拷貝
1、遞迴法
遞迴法複製所有層級的屬性。
function deepClone(obj){ let objClone = Array.isArray(obj)?[]:{}; if(obj && typeof obj==="object"){ for(key in obj){ if(obj.hasOwnProperty(key)){ //判斷ojb子項目是否為對象,如果是,遞迴複製 if(obj[key]&&typeof obj[key] ==="object"){ objClone[key] = deepClone(obj[key]); }else{ //如果不是,簡單複製 objClone[key] = obj[key]; } } } } return objClone;} let a=[1,2,3,4], b=deepClone(a);a[0]=2;console.log(a,b);
控制台列印出來的:
b 沒有受a 影響,所以是深拷貝。
但是:
拷貝的不徹底啊,b對象的一級屬性確實不受影響了,但是二級屬性還是沒能拷貝成功,仍然脫離不了a的控制,說明slice根本不是真正的深拷貝。
2、JSON對象的parse和stringify
function deepClone(obj){ let _obj = JSON.stringify(obj), objClone = JSON.parse(_obj); return objClone} let a=[0,1,[2,3],4], b=deepClone(a);a[0]=1;a[2][0]=1;console.log(a,b);
b不受a的影響,實現了深拷貝。
3、除了上面兩種方法之外,我們還可以借用JQ的extend方法。
deep表示是否深拷貝,為true為深拷貝,為false,則為淺拷貝
target Object類型 目標對象,其他對象的成員屬性將被附加到該對象上。
object1 objectN可選。 Object類型 第一個以及第N個被合并的對象。
let a=[0,1,[2,3],4], b=$.extend(true,[],a);a[0]=1;a[2][0]=1;console.log(a,b);
實現深拷貝。
js中的深拷貝與淺拷貝