深復制和淺復制只針對像 Object, Array 這樣的復雜對象的。簡單來說,淺復制只復制一層對象的屬性,而深復制則遞歸復制了所有層級。
深淺拷貝 的主要區別就是:復制的是引用(地址)還是復制的是實例。
所謂
深淺拷貝:
對於僅僅是復制了引用(地址),換句話說,復制了之后,原來的變量和新的變量指向同一個東西,彼此之間的操作會互相影響,為
淺拷貝。
而如果是在堆中重新分配內存,擁有不同的地址,但是值是一樣的,復制后的對象與原來的對象是完全隔離,互不影響,為
深拷貝。
下面是一個簡單的淺復制實現:
var obj = { a:1, arr: [2,3] }; var shallowObj = shallowCopy(obj); function shallowCopy(src) { var dst = {}; for (var prop in src) { if (src.hasOwnProperty(prop)) { dst[prop] = src[prop]; } } return dst; }
因為淺復制只會將對象的各個屬性進行依次復制,並不會進行遞歸復制,而 JavaScript 存儲對象都是存地址的,所以淺復制會導致 obj.arr 和 shallowObj.arr 指向同一塊內存地址,大概的示意圖如下。
導致的結果就是:
shallowObj.arr[1] = 5; obj.arr[1] // = 5
而深復制則不同,它不僅將原對象的各個屬性逐個復制出去,而且將原對象各個屬性所包含的對象也依次采用深復制的方法遞歸復制到新對象上。這就不會存在上面 obj 和 shallowObj 的 arr 屬性指向同一個對象的問題。
var obj = { a:1, arr: [1,2] }; var obj2 = deepCopy(obj);
結果如下面的示意圖所示:
需要注意的是,如果對象比較大,層級也比較多,深復制會帶來性能上的問題。在遇到需要采用深復制的場景時,可以考慮有沒有其他替代的方案。在實際的應用場景中,也是淺復制更為常用。
深拷貝 對象和數組實例分析(問題在哪?)
var cloneObj = function(obj){ var str, newobj = obj.constructor === Array ? [] : {}; if(typeof obj !== 'object'){ return; } else if(window.JSON){ str = JSON.stringify(obj), //系列化對象 newobj = JSON.parse(str); //還原 } else { for(var i in obj){ newobj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i]; } } return newobj; };
作者:知乎用戶
鏈接:https://www.zhihu.com/question/23031215/answer/46220227
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
【 js 基礎 】【 源碼學習 】 深淺拷貝