深淺拷貝方法

2021-10-03 16:03:20 字數 2682 閱讀 3164

let a = 

let b = a

a.age = 2

console.log(b.age) // 2

首先可以通過object.assign來解決這個問題,很多人認為這個函式是用來深拷貝的。其實並不是,object.assign只會拷貝所有的屬性值到新的物件中,如果屬性值是物件的話,拷貝的是位址,所以並不是深拷貝。

let a = 

let b = object.assign({}, a)

a.age = 2

console.log(b.age) // 1

另外我們還可以通過展開運算子...來實現淺拷貝

let a = 

let b =

a.age = 2

console.log(b.age) // 1

通常淺拷貝就能解決大部分問題了,但是當我們遇到如下情況就可能需要使用到深拷貝了

let a = 

}let b =

a.jobs.first = 'native'

console.log(b.jobs.first) // native

淺拷貝只解決了第一層的問題,如果接下去的值中還有物件的話,那麼就又回到最開始的話題了,兩者享有相同的位址。要解決這個問題,我們就得使用深拷貝了。

這個問題通常可以通過json.parse(json.stringify(object))來解決。

let a = 

}let b = json.parse(json.stringify(a))

a.jobs.first = 'native'

console.log(b.jobs.first) // fe

但是該方法也是有侷限性的:

let obj = ,

}obj.c = obj.b

obj.e = obj.a

obj.b.c = obj.c

obj.b.d = obj.b

obj.b.e = obj.b.c

let newobj = json.parse(json.stringify(obj))

console.log(newobj)

在遇到函式、undefined或者symbol的時候,該物件也不能正常的序列化

let a = ,

name: 'yck'

}let b = json.parse(json.stringify(a))

console.log(b) //

你會發現在上述情況中,該方法會忽略掉函式和undefined

但是在通常情況下,複雜資料都是可以序列化的,所以這個函式可以解決大部分問題。

如果你所需拷貝的物件含有內建型別並且不包含函式,可以使用messagechannel

function structuralclone(obj)  = new messagechannel()

port2.onmessage = ev => resolve(ev.data)

port1.postmessage(obj)

})}var obj =

}obj.b.d = obj.b

// 注意該方法是非同步的

// 可以處理 undefined 和迴圈引用物件

const test = async () =>

test()

當然你可能想自己來實現乙個深拷貝,但是其實實現乙個深拷貝是很困難的,需要我們考慮好多種邊界情況,比如原型鏈如何處理、dom 如何處理等等,所以這裡我們實現的深拷貝只是簡易版,並且我其實更推薦使用 lodash 的深拷貝函式。

function deepclone(obj) 

if (!isobject(obj))

let isarray = array.isarray(obj)

let newobj = isarray ? [...obj] :

reflect.ownkeys(newobj).foreach(key => )

return newobj

}let obj =

}let newobj = deepclone(obj)

newobj.b.c = 1

console.log(obj.b.c) // 2

// 定義乙個深拷貝函式  接收目標target引數

function deepclone(target)

// 判斷如果當前的值是null的話;直接賦值為null

} else if(target===null) else if(target.constructor===regexp)else ;

for (let i in target)

}// 如果不是物件的話,就是基本資料型別,那麼直接賦值

} else

// 返回最終結果

return result;

}

深淺拷貝以及深淺拷貝的方法

先考慮一種情況,對乙個已知物件進行拷貝,編譯系統會自動呼叫一種建構函式 拷貝建構函式,如果使用者未定義拷貝建構函式,則會呼叫預設拷貝建構函式。執行結果 呼叫一次建構函式,呼叫兩次析構函式,兩個物件的指標成員所指記憶體相同,name指標被分配一次記憶體,但是程式結束時該記憶體卻被釋放了兩次,會造成記憶...

拷貝和深淺拷貝

當list2為list的拷貝物件時,list內的可變資料型別變化,list2變化 list內的不可變資料型別變化,list2變化。總之 list變化list2一定變化 list 1,2,3,4,list2 list print list print list2 1,2,3,4,5 1,2,3,4,5...

操作字元 物件方法, 深淺拷貝

在乙個專案中,我們通常會通過例如substring,slice,concat等一些方法來操作字元,陣列,物件來獲取我們想要的結果 首先我覺得,所有的操作應該對深淺拷貝有乙個認識,因為有時候我們需要利用淺拷貝的特性來達到一些功能效果,更多的時候我們需要深拷貝來複製物件和陣列,在不影響原有資料的基礎上來...