若是复制引用,复制后的引用都是指向同一个对象的实例,彼此之间的操做会互相影响。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"; }