欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解lodash中的cloneDeep使用細(xì)節(jié)

 更新時間:2023年01月26日 09:30:50   作者:flyingbird  
這篇文章主要為大家介紹了詳解lodash中的cloneDeep使用細(xì)節(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

lodash中的cloneDeep是一個使用頻率比較高的方法,然而你真的理解其中的細(xì)節(jié)處理嗎?如果下面幾個問題你還有疑惑那么本文對你或多或少有些幫助。

  • cloneDeep中支持拷貝函數(shù)、Error對象、DOM節(jié)點(diǎn)以及WeakMap對象嗎?
  • cloneDeep中使用了哪種算法呢?
  • 瀏覽器中提供的實(shí)現(xiàn)深拷貝的方式除了JSON.parse(JSON.stringify()),還有其他方法嗎?
  • 當(dāng)遇到循環(huán)引用時,如何進(jìn)行深拷貝操作來避免出現(xiàn)棧溢出呢?

當(dāng)上面這些問題你還有疑惑時,可能會在一些比較少見的場景中遇到一些出乎意料的問題,希望本文能夠?qū)δ阌兴鶐椭?/p>

支持的數(shù)據(jù)類型

lodash中支持了很多種的數(shù)據(jù)類型,包括 arrays、array buffers、 booleans、 date objects、maps、 numbers、Object、regexes、sets、 strings、symbols、typed arrays,以及包括arguments這個參數(shù)(不過拷貝后會丟失一些信息)。

但是由于一些原因,還有一些類型,lodash中默認(rèn)時不支持的。至于error objects、functions、DOM nodes、以及WeakMaps默認(rèn)是不支持的,lodash默認(rèn)會返回一個控對象,所以如果數(shù)據(jù)中存在這些數(shù)據(jù)類型時需要特別關(guān)注一下,拷貝之后就無法獲取對應(yīng)的數(shù)據(jù)了。

cloneDeepWith

如果拷貝的數(shù)據(jù)中存在不支持的數(shù)據(jù)類型時,我們改怎么辦呢?

lodash為我們提供了另外一個方法,與cloneDeep比較類似,只不過我們可以在這個方法中傳入一個自定義函數(shù),當(dāng)遇到不支持的數(shù)據(jù)類型時,我們可以根據(jù)場景來定義自己的深拷貝的實(shí)現(xiàn)邏輯。比如說當(dāng)拷貝函數(shù)時,返回函數(shù)本身等。

lodash官網(wǎng) 有著比較詳細(xì)的例子,也可以參考一下。

拷貝算法介紹

lodash作為一個使用非常廣泛的庫,在拷貝算法上使用了structured clone algorithm,這個算法細(xì)節(jié)描述可以參考 html.spec.whatwg.org/multipage/s… ,與目前瀏覽器中的structuredClone方法實(shí)現(xiàn)采用的是一樣的算法,在其他一些場景中大家進(jìn)行拷貝方式的實(shí)現(xiàn)基本是一致的,這也保證了使用cloneDeep方法具有良好的兼容性。

structuredClone VS cloneDeep

目前瀏覽器中提供了structuredClone 方法來處理需要深拷貝的場景,那我們還需要使用lodash提供的cloneDeep方法嗎?從目前來看這個API在web場景的兼容性:

目前看來兼容性還不是特別高,大家可以根據(jù)自己的場景來進(jìn)行選用,畢竟使用lodash會增加包體積大小,對于一些追求極致性能的場景包體積肯定越小越好。

循環(huán)引用處理方法

在處理拷貝過程中一般都會遇到一個比較棘手的問題:循環(huán)引用, 看下面這段簡單的代碼:

const objb = {
  b: null
};
const obja = {
  a: objb
};
objb.b = obja;
console.log(objb);

在控制臺中輸出objb對象,展開其屬性,我們可以看到這個結(jié)果:

可以看到objb對象的屬性可以無限展開下去,這樣就形成了循環(huán)引用。形成循環(huán)引用的原因就是,objb.b引用了obja對象;但是obja.a屬性又引用了objb對象。

如果我們進(jìn)行不斷的拷貝而不做針對循環(huán)引用的處理,必然會出現(xiàn)這個錯誤:

那么lodash中是如何處理這個問題的呢?

其實(shí)lodash中處理循環(huán)引用的方法非常簡單清晰,下面這段代碼是處理循環(huán)引用的核心代碼。可以看出lodash中主要通過緩存每個值對應(yīng)的拷貝結(jié)果來解決循環(huán)引用的問題。

針對上面的這個存在循環(huán)引用的對象,我們可以來按步驟進(jìn)行分析一下cloneDeep(objb)時是如何解決循環(huán)引用的:

  • 處理objb對象,stack.get(objb)不存在,所以將代表objb的拷貝結(jié)果result放到stack中,然后逐個處理objb上的屬性
  • 處理objb中的b屬性,stack.get(obj.b)其實(shí)也就是stack.get(obja),此時stacka也在stack中,因此也將代表obja的拷貝結(jié)果result放置到stack中,然后逐個處理obja上的屬性
  • 處理obja上的a屬性,stack.get(obja.a)其實(shí)也就是stack.get(objb),經(jīng)過前兩步的處理,我們只在此時,objb已經(jīng)存在stack中了,stack.get(objb)返回一個拷貝后的對象

拷貝過程結(jié)束,返回拷貝的結(jié)果 可以結(jié)合下面這幅圖來進(jìn)行理解:

總結(jié)

深拷貝看起來簡單,但是實(shí)現(xiàn)中有很多細(xì)節(jié)需要注意,lodash這類工具庫確實(shí)幫我們解決了不少問題,感謝開源!

以上就是詳解lodash中的cloneDeep使用細(xì)節(jié)的詳細(xì)內(nèi)容,更多關(guān)于lodash cloneDeep使用的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論