前言
*在js中,數(shù)組和對(duì)象的復(fù)制如果使用=號(hào)來(lái)進(jìn)行復(fù)制,那只是淺拷貝。如下圖演示: *
image
如上,arr的修改,會(huì)影響arr2的值,這顯然在絕大多數(shù)情況下,并不是我們所需要的結(jié)果。
因此,數(shù)組以及對(duì)象的深拷貝就是javascript的一個(gè)基本功了。
ps:要實(shí)現(xiàn)完全的深層次拷貝,既拷貝所有層級(jí)的屬性。并且不會(huì)丟失數(shù)據(jù)。只有一種方法,那就是遞歸遍歷所有層。
function deepCopy(obj) {
let clonedObj;
// 判斷直接數(shù)據(jù)類型
if (['number', 'string', 'boolean', 'undefined', 'symbol',].includes(typeof obj)
|| obj === null) {
clonedObj = obj;
return clonedObj;
}
const constructor = obj.constructor || Object;
clonedObj = new constructor();
Object.entries(obj).forEach(([key, value]) => {
clonedObj[key] = deepCopy(value);
})
return clonedObj;
}
可能很多人說(shuō)有很多方法啊,JSON.stringify然后再JSON.parse,這個(gè)方法其實(shí)也是深拷貝,但是有如下風(fēng)險(xiǎn)
- 1、如果obj里面有時(shí)間對(duì)象,則JSON.stringify后再JSON.parse的結(jié)果,時(shí)間將只是字符串的形式,而不是對(duì)象的形式
- 2、如果obj里面有RegExp,則打印出來(lái)是空對(duì)象
- 3、如果對(duì)象中有函數(shù)或者undefined,則會(huì)直接被丟掉
- 4、如果json里有對(duì)象是由構(gòu)造函數(shù)生成的,則會(huì)丟掉對(duì)象的constructon
- 5、如果對(duì)象中存在循環(huán)引用的情況也無(wú)法正確實(shí)現(xiàn)深拷貝
- 6、如果對(duì)象中存在NAN,則序列化后會(huì)變成null