日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

对象数组的深浅拷贝

發布時間:2023/12/31 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对象数组的深浅拷贝 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
作者:知乎用戶
鏈接: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函數?

對于array對象的slice函數, 返回一個數組的一段。(仍為數組) arrayObj.slice(start, [end]) 參數 arrayObj 必選項。一個 Array 對象。 start 必選項。arrayObj 中所指定的部分的開始元素是從零開始計算的下標。 end 可選項。arrayObj 中所指定的部分的結束元素是從零開始計算的下標。 說明 slice 方法返回一個 Array 對象,其中包含了 arrayObj 的指定部分。 slice 方法一直復制到 end 所指定的元素,但是不包括該元素。如果 start 為負,將它作為 length + start處理,此處 length 為數組的長度。如果 end 為負,就將它作為 length + end 處理,此處 length 為數組的長度。如果省略 end ,那么 slice 方法將一直復制到 arrayObj 的結尾。如果 end 出現在 start 之前,不復制任何元素到新數組中。 ? var arr = ["One","Two","Three"];var arrtoo = arr.slice(0); arrtoo[1] = "set Map"; document.writeln("數組的原始值:" + arr + "<br />");//Export:數組的原始值:One,Two,Three document.writeln("數組的新值:" + arrtoo + "<br />");//Export:數組的新值:One,set Map,Three

?

方法二: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

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的对象数组的深浅拷贝的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。