javascript之深淺拷貝

爲什麼寫:

最近在研究深淺拷貝,找了不少資料,感受不是很滿意,因此本身就整理了一份。廢話很少說,咱們來一塊兒複習一下吧,也但願留下您寶貴意見。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 函數的實現,這裏就不具體說了。

參考文檔:
冴羽的JavaScript專題之深淺拷貝
Alloyteam深拷貝與淺拷貝的實現

相關文章
相關標籤/搜索