標籤:span 分享 地址 原來 function 方法 全域對象 排除 com
Shallow copy && Deep copy
對於字串類型,淺複製是對值的複製,對於對象來說,
淺複製是對對象地址的複製,並沒 有開闢新的棧,也就是複製的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另一個對象的屬性也會改變,舉個栗子
var arr = [1,2,3];var arrCopy = arr;arrCopy[0] = 100; // 修改新數組的第0個值;arr[0]===arrCopy[0]; //true 原來的數組四不四也變了
而很多數情況下我們需要的是 新得到的對象與原來的對象互不相干,於是乎:
深複製則是開闢新的棧,兩個對象對應兩個不同的地址,修改一個對象的屬性,不會改變另一個對象的屬性。我們來看看以下方法。
Array 的 slice 和 concat 方法
//slicevar a = [1,2,3];var b = a.slice(); b === a; // false//concatvar a = [1,2,3];var b = a.concat(); b === a; // false你可能會說你看他們沒有指向同一個地址啊,喵的肯定是 deep copy,表捉急。請看下面:var a = [[1,2,3],4,5];var b = a.slice();a[0][0]===b[0][0]; // true true 了我去,第二層的複製明顯不是 deep copy 啊。
jQuery —— $.extend()
我們可以通過 $.extend()
方法來完成 深淺複製。這個方法可以傳入一個參數:deep(true or false),表示是否執行深複製(如果是深複製則會執行遞迴複製)。
var x = { a: 1, b: 2, c: {f:{g:1}}};var y = $.extend({}, x), //淺 copy z = $.extend(true, {}, x); //深 copyy.c.f === x.c.f // truez.c.f === x.c.f // false $.extend 的用法很有意思,不單單只是 深淺copy, 有興趣的崽兒可以到這個同學這裡看看,總結的挺好 1190000004082170
藉助 JSON 全域對象
針對純 JSON 資料對象的深複製,使用 JSON 全域對象的 parse
和 stringify
方法來實現深複製也算是一個簡單討巧的方法。
JOSN 對象中的 stringify 可以把一個 js 對象序列化為一個 JSON 字串,parse 可以把 JSON 字串還原序列化為一個 js 對象,這兩個方法實現的是深拷貝。然而使用這種方法會有一些隱藏的坑,
它能正確處理的對象只有 Number, String, Boolean, Array, 扁平對象(function 就歇菜了,原型鏈也沒了),即那些能夠被 json 直接表示的資料結構。
var arr = [0,1,2];var arrCopy = JSON.parse(JSON.stringify(arr));arrCopy[0] = 333;
arr[0]===arrCopy[0]; // false
did u see that, 互不干擾,和諧盛世。
總結下:
Array 的 slice 和 concat 方法 和 jQuery 中的 extend 複製方法,他們都會複製第一層的值,對於 第一層 的值都是 深拷貝,
而到 第二層 的時候 Array 的 slice 和 concat 方法就是 複製引用 ,jQuery 中的 extend 複製方法 則 取決於 你的 第一個參數, 也就是是否進行遞迴複製。
而 JSON.parse(JSON.stringify(arr)) 在排除 被複製對象的 function 和原型鏈 之外,就是完全的複製啦 。
今天,就醬紫。88了。
js 中的深拷貝和淺拷貝