深拷貝真難

2021-10-17 14:53:49 字數 1606 閱讀 3268

深拷貝淺拷貝的原理我是已經懂了,之前也有分享過。只是深拷貝淺拷貝的方法卻從來沒有真的去了解過。

想想之前的面試,問到深拷貝淺拷貝的時候,都是說一下原理,問到方法,張口就來json.parse和json.stringify,如果有函式的話就遞迴迴圈拷貝。卻從來沒有寫過遞迴或者迴圈拷貝的函式。

今天寫了一下深拷貝資料的函式,發現深拷貝其實好難好難,單單乙個資料的深拷貝就讓我覺得腦殼都受不了了,更別說一些大佬們還提到了原型鏈、dom、regexp、函式、瀏覽器內建函式之類的是否拷貝或者說怎麼處理,再加上相容,以後出去再也不敢說能寫出深拷貝函式了。

今天也不是寫個什麼好的深拷貝函式,單純的寫一下資料處理的深拷貝,雖然對於json物件的深拷貝json.parse和json.stringify是最簡單的,只是讓自己稍微見見世面。

function clone(data) ;

for(var i in data)

}if(isarray(data))

}return target;

}function isobject(x)

function isarray(x)

很簡單,判斷傳進來的引數是否是陣列或者物件,這邊對陣列或者物件的判斷比較嚴格,如果是就分別迴圈遞迴拷貝子物件。這只是對物件和陣列的深拷貝。for in我們都知道會遍歷出自身和原型鏈上可列舉的屬性,有時候我們是不想拷貝這些的。所以這邊相容就要在for in裡面加上data.hasownproperty的判斷。

基本上遞迴的拷貝都能理解,但是如果乙個資料層級太多,會出現爆棧:

maximum call stack size exceeded

包括json.parse和json.stringify也會。

這時候就要迴圈深拷貝了,直接上**:

function cloneloop(x) ;

};if(isarray(x))

const looplist = [

];while(looplist.length) ;

};if(isarray(data))

}if(isobject(data))

}if(isarray(data))}}

function initlooplist(val, key, res) );

} else

}return target;

}function isobject(val)

function isarray(val)

我自己都不知道要這麼去注釋這個函式,精華就是這兩個引用:

res = parent[key] = {};

res = parent[key] = ;

就是對引用稍微繞了一點,可以自己理解一下。

深拷貝暫時只能是了解到這種程度了,當然,一般來說資料不會有這麼深的層級。這只是最簡單的對陣列物件的拷貝,沒有涉及函式、dom或者原型鏈這些,連資料的引用都沒考慮進去,比如:

let a = {};

let b = ;

這種情況還得考慮是否保留引用還是建立新的。

淺拷貝 深拷貝

copy mutablecopy copy 不管是可變的,還是不可變的,結果都是不可變的 mutablecopy 不管是不可變的,還是可變的,結果都是可變的 nsmutablestring str nsmutablestring stringwithformat a nsarray arr1 str...

深拷貝 淺拷貝

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...

淺拷貝 深拷貝

retain是建立乙個指標,引用物件計數加1。copy屬性表示兩個物件內容相同,新的物件retain為1 與舊有物件的引用計數無關,舊有物件沒有變化。copy減少物件對上下文的依賴。retain屬性表示兩個物件位址相同 建立乙個指標,指標拷貝 內容當然相同,這個物件的retain值 1也就是說,re...