最近在研究深淺拷貝,找了不少資料,感受不是很滿意,因此本身就整理了一份。廢話很少說,咱們來一塊兒複習一下吧,也但願留下您寶貴意見。git
深拷貝和淺拷貝是隻針對Object和Array這樣的複雜類型的
1.淺拷貝:github
咱們先來看2個栗子:數組
let a = { name: 'azi' } let b = a; b.name = 'zhangsan'; console.log(a.name); // zhangsan console.log(b.name); // zhangsan
let a = ['hello','world'] let b = a; b[1]= 'azi'; console.log(a); // ["hello", "azi"] console.log(b); // ["hello", "azi"]
從栗子中能夠看出:安全
a和b指向同一塊內存,因此修改其中任意的值,另外一個值都會隨之變化,這就是淺拷貝。
2.深拷貝:函數
若是給b放到新的內存中,將a的各個屬性都複製到新內存裏,就是深拷貝。
換句話說,也就是b的屬性改變時,a的屬性不會跟着變化。this
1.淺拷貝:code
數組:對象
Array.slice()、 Array.concat()、 ...
對象:ip
Object.assign()、 ...
栗子:內存
// concat concat方法不會改變this或任何做爲參數提供的數組,而是返回一個淺拷貝,它包含與原始數組相結合的相同元素的副本 let arr = ['old', 1, true, null, undefined]; let new_arr1 = arr.concat(); new_arr1[0] = 'new'; console.log(arr) // ["old", 1, true, null, undefined] console.log(new_arr1) // ["new", 1, true, null, undefined] // slice slice()方法返回一個從開始到結束(不包括結束)選擇的數組的一部分淺拷貝到一個新數組對象 let new_arr2 = arr.slice(); new_arr2[0] = 'new'; console.log(arr) // ["old", 1, true, null, undefined] console.log(new_arr2) // ["new", 1, true, null, undefined] // ... 擴展運算符 複製數組時候, 拓展語句只會進行淺複製, 所以以下所示, 它並不適合複製多維數組 (與Object.assign() 相同 let new_arr3 = [...arr]; new_arr3[0] = 'new'; console.log(arr) // ["old", 1, true, null, undefined] console.log(new_arr3) // ["new", 1, true, null, undefined]
// Object.assign() Object.assign方法只會拷貝源對象自身的而且可枚舉的屬性到目標對象 let obj1 = {a:0, b:{c:0}}; let obj2 = Object.assign({},obj1); obj2.b.c =2 ; obj2.a =2 ; console.log(obj1); // {a:0,b:{c:2}} console.log(obj2); // {a:2,b:{c:2}} // ... let obj3 = {...obj1}; obj3.b.c =3 ; obj3.a =3 ; console.log(obj1); // {a:0,b:{c:3}} console.log(obj3); // {a:3,b:{c:3}}
2.深拷貝:
JSON.parse( JSON.stringify(arr) )
在使用JSON.stringify() 須要注意一下幾點:
1.JSON.stringify(..) 在將 JSON 對象序列化爲字符串時和 toString() 的效果基本相同,只不過序列化的結 果老是字符串:
JSON.stringify( 42 ); // "42"
JSON.stringify( "42" ); // ""42""(含有雙引號的字符串)
JSON.stringify( null ); // "null"
JSON.stringify( true ); // "true"
2.全部安全的 JSON 值(JSON-safe)均可以使用 JSON.stringify(..) 字符串化。安全的 JSON 值是指可以呈現爲有效 JSON 格式的值。
3.undefined、function、symbol (ES6+)和包含循環引用(對象之間相互引用,造成一個無限循環)的對象都不符合 JSON結構標準,支持 JSON 的語言沒法處理它們
4.JSON.stringify(..) 在對象中遇到 undefined、function 和 symbol 時會自動將其忽略,在
數組中則會返回 null(以保證單元位置不變)。
例如:
JSON.stringify( undefined ); // undefined JSON.stringify( function(){} ); // undefined JSON.stringify([1,undefined,function(){},4]); // "[1,null,null,4]" JSON.stringify({ a:2, b:function(){} }) // "{"a":2}"
對包含循環引用的對象執行 JSON.stringify(..) 會出錯。
固然也能夠用JQ的extend 函數的實現,這裏就不具體說了。