我們使用object.assign(target,…sources)時,其實只是淺拷貝。只能複製第一層屬性,而如果第一層屬性中有物件或陣列的話,其實只是對物件或陣列的引用而已。
我們修改target裡的物件屬性時,source物件中對應的物件屬性也會改變
let source =
}let target =
object.
assign
(target, source)
target.obj.name =
'change'
console.
log(target.obj.name)
//change
console.
log(source.obj.name)
//change
要想實現深拷貝:
function
deepcopy
(target, source)
for(
let i in source)
deepcopy
(target[i]
, source[i])}
else}}
}
需要注意的是 for …in 迴圈中讀取出來的變數都轉換成string了,所以在遞迴傳參一定要注意用
deepcopy(target[i], source[i])
2020.9.6記
上面的深拷貝僅僅實現了物件的深拷貝,沒有考慮到陣列的情況。下面**兼具了陣列和物件:
function
deepcopy
(target));
}else
if(object.prototype.tostring.
call
(target)
==="[object object]");
object.
keys
(target)
.foreach
((key)
=>);
}else
return result;
}
順便總結一下js判斷資料型別的幾種方式和優缺點。
object.prototype.tostring.
call()
//這個方法是最好了,可以明確的區分各種型別
typeof
//這個區分不出來陣列和物件和null。
array.
isarray()
//這個用來區分陣列
instanceof
//無法區分null 和 undefined
2020 9.30
在面試的時候被問到乙個問題,再進行深拷貝時遇到迴圈引用時怎麼辦?
當時一下子懵了,從倆沒有想過這樣的問題。
查了一下,解決方法應該是 用乙個 map 來儲存引用型別,然後每次遇到引用屬性時,就用 has 檢視是否已經有了這個引用。
function
deepcopy
(target, map)
let result = array.
isarray
(target)?[
]:; object.
keys
(target)
.foreach
((property)
=>
else
else}}
);return result;
}
原生JS 實現複雜物件深拷貝(物件值包含函式)
以前對深拷貝和淺拷貝沒有太深的印象,後來才知道是因為沒掉進去過它的坑里。最近掉坑了才意識到它們的重要性。閒話少敘,來說說坑 如果我需要儲存乙個複雜的物件 obj 並把它賦值給 originalobj 後來對obj物件的某個屬性值進行了修改,然後,我儲存的初始值originalobj 也被修改了!這個...
原生JS 實現複雜物件深拷貝(物件值包含函式)
以前對深拷貝和淺拷貝沒有太深的印象,後來才知道是因為沒掉進去過它的坑里。最近掉坑了才意識到它們的重要性。閒話少敘,來說說坑 如果我需要儲存乙個複雜的物件 obj 並把它賦值給 originalobj 後來對obj物件的某個屬性值進行了修改,然後,我儲存的初始值originalobj 也被修改了!這個...
js 物件深拷貝 js淺拷貝及深拷貝的幾種方法
乙個專案開發中經常會用到需要複製乙個物件或者陣列,但是卻不能改變原始物件,所以就要用到拷貝,拷貝又分深拷貝和淺拷貝,今天列舉一下幾種拷貝形式。object.assign我們經常會用到合併物件,當然利用object.assign性質我們也可以實現物件的拷貝。var obj1 var obj2 obje...