对象数组的深浅拷贝
作者:知乎用戶
鏈接:https://www.zhihu.com/question/23031215/answer/46220227
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
下面我們來看幾個深淺拷貝的案例
鏈接:https://www.zhihu.com/question/23031215/answer/46220227
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
首先深復制和淺復制只針對像 Object, Array 這樣的復雜對象的。簡單來說,淺復制只復制一層對象的屬性,而深復制則遞歸復制了所有層級。
拋開jQuery,上代碼例子。下面是一個簡單的淺復制實現:
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 指向同一塊內存地址,大概的示意圖如下。
<img src="https://pic4.zhimg.com/50/v2-39761dfd012733879e0d100ec260a5d7_hd.png" data-rawwidth="646" data-rawheight="241" class="origin_image zh-lightbox-thumb" width="646" data-original="https://pic4.zhimg.com/v2-39761dfd012733879e0d100ec260a5d7_r.png">導致的結果就是:
shallowObj.arr[1] = 5; obj.arr[1] // = 5而深復制則不同,它不僅將原對象的各個屬性逐個復制出去,而且將原對象各個屬性所包含的對象也依次采用深復制的方法遞歸復制到新對象上。這就不會存在上面 obj 和 shallowObj 的 arr 屬性指向同一個對象的問題。
var obj = { a:1, arr: [1,2] }; var obj2 = deepCopy(obj);結果如下面的示意圖所示:
<img src="https://pic1.zhimg.com/50/6604224933c95787764d941432a1f968_hd.jpg" data-rawwidth="3264" data-rawheight="1224" class="origin_image zh-lightbox-thumb" width="3264" data-original="https://pic1.zhimg.com/6604224933c95787764d941432a1f968_r.jpg">需要注意的是,如果對象比較大,層級也比較多,深復制會帶來性能上的問題。在遇到需要采用深復制的場景時,可以考慮有沒有其他替代的方案。在實際的應用場景中,也是淺復制更為常用。
下面我們來看幾個深淺拷貝的案例
在使用JavaScript對數組進行操作的時候,我們經常需要將數組進行備份,事實證明如果只是簡單的將它賦予其他變量,那么我們只要更改其中的任何一個,然后其他的也會跟著改變,這就導致了問題的發生。
var arr = ["One","Two","Three"];var arrto = arr; arrto[1] = "test"; document.writeln("數組的原始值:" + arr + "<br />");//Export:數組的原始值:One,test,Three document.writeln("數組的新值:" + arrto + "<br />");//Export:數組的新值:One,test,Three像上面的這種直接賦值的方式就是淺拷貝,很多時候,這樣并不是我們想要得到的結果,其實我們想要的是arr的值不變,不是嗎??
方法一:js的slice函數?
?
方法二:js的concat方法?
concat() 方法用于連接兩個或多個數組。 該方法不會改變現有的數組,而僅僅會返回被連接數組的一個副本。 語法 arrayObject.concat(arrayX,arrayX,......,arrayX) 說明 返回一個新的數組。該數組是通過把所有 arrayX 參數添加到 arrayObject 中生成的。如果要進行 concat() 操作的參數是數組,那么添加的是數組中的元素,而不是數組。 ? var arr = ["One","Two","Three"];var arrtooo = arr.concat(); arrtooo[1] = "set Map To"; document.writeln("數組的原始值:" + arr + "<br />");//Export:數組的原始值:One,Two,Three document.writeln("數組的新值:" + arrtooo + "<br />");//Export:數組的新值:One,set Map To,Three?
二、對象的深淺拷貝
var a={name:'yy',age:26}; var b=new Object();b.name=a.name; b.age=a.age; a.name='xx'; console.log(b);//Object { name="yy", age=26} console.log(a);//Object { name="xx", age=26}就是把對象的屬性遍歷一遍,賦給一個新的對象。
var deepCopy= function(source) { var result={}; for (var key in source) { result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key]; } return result; }轉載于:https://www.cnblogs.com/wp-js/p/7802391.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
- 上一篇: 微博国际版网页(微博搜索的微博)
- 下一篇: sql 查询模块