若是複製引用,複製後的引用都是指向同一個對象的實例,彼此之間的操做會互相影響。javascript
深複製不是簡單的複製引用,而是在堆中從新分配內存,而且把源對象實例的全部屬性都進行新建複製,以保證深複製的對象的引用圖不包含任何原有對象或對象圖上的任何對象,複製後的對象與原來的對象是徹底隔離的。java
利用數組方法slice和concat返回新數組特性,進行復制。數組
var arr = [1,2,3]; var new_arr = arr.concat(); arr[0] = 'new'; console.log(new_arr); //[1, 2, 3]
再來看一組狀況:this
var arr = [{name: 'haha'}, [1,2,3]]; var new_arr = arr.concat(); arr[0].name = "lily"; console.log(new_arr.name); //"lily"
能夠看出,若是數組元素是基本數據類型,就會複製一份,互不影響,而若是是對象或者數組,就會只複製對象和數組的引用。code
var obj = { name: "jack" }; var a = [1, 2]; var b = [3, obj]; a.push(...b); a // [1, 2, 3, {name: "jack"}] a[3].name = "rose"; b // [3, {name: "rose"}]
var obj = { name: "jack" }; var copyObj = Object.assign({}, obj); obj.name = "rose"; copyObj // {name: "rose"}
function shallowCopy(obj) { if (typeof obj !== 'object') return; var new_obj = obj instanceof Array ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { new_obj[key] = obj[key]; } } return new_obj; } var source = { name: "source", child: { name:"child" }, arr: [1,2,34], setName: function() { this.name = "haha"; } }; var target = shallowCopy(source); console.log(target); //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function } source.child.name = "lily"; console.log(target.child.name); //"lily" source.name = "sam"; console.log(target.name); //"source" source.arr[0] = 5; console.log(target.arr); //"5,2,34" source.setName = function() { console.log(this.name); }; console.log(target.setName ); //function(){ this.name = "haha"; }
由此能夠看出,此方法確實能夠複製object和array對象,但沒法進行深複製;可是能夠複製function。對象
利用JSON對象的parse和stringify方法。ip
var source = { name: "source", child: { name:"child" }, arr: [1,2,34], setName: function() { this.name = "haha"; } }; var target = JSON.parse(JSON.stringify(source)); console.log(target); //Object {name: "source", child:{ name:"child"}, arr:[1,2,34] } source.child.name = "lily"; console.log(target.name); //"child" source.arr[0] = 5; console.log(target.arr); //"1,2,34"
由此能夠看出,雖然此方法確實能夠複製object和array對象,而且進行了深複製,卻沒法複製function。內存
function deepCopy(obj) { if (typeof obj !== 'object') return; var new_obj = obj instanceof Array ? [] : {}; for (var key in obj) { if (obj.hasOwnProperty(key)) { new_obj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]; } } return new_obj; } var source = { name: "source", child: { name:"child" }, arr: [1,2,34], setName: function() { this.name = "haha"; } }; var target = deepCopy(source); console.log(target); //Object {name: "source", child:{ name:"child"}, arr: [1,2,34], setName: function } source.child.name = "lily"; console.log(target.child.name); //"child" source.name = "sam"; console.log(target.name); //"source" source.arr[0] = 5; console.log(target.arr); //"1,2,34" source.setName = function() { console.log(this.name); }; console.log(target.setName ); //function(){ this.name = "haha"; }