对一个对象或者数组这种引用类型的值进行复制能够分为浅复制和深复制,好比这样的一个对象数组
let obj={ a:1, b:{ a:1, b:2 }, c:3 }
很明显这个对象是存在两层的,obj[b]不是基本类型值,而是另外一个对象。若是使用浅复制去拷贝这个对象的话,那么拷贝出来新的对象的b属性的值是原来对象b属性的引用地址,也就是说,若是改变源对象的b属性,新的对象也会受到影响,由于咱们只使用浅复制拷贝了一层。函数
上面讲的就是浅复制,在实际应用中存在很严重的问题。因此咱们通常复制对象都是用深复制,深复制不是简单的复制一层,而是遍历整个对象,一直到获取到的值不是引用类型,而是基本类型的时候才进行复制,这样就使得新的对象跟原来的对象彻底是两个不一样的对象了。code
下面是我写的一个简单的深复制函数对象
let obj={ a:1, b:{ a:1, b:2 }, c:3 } function deepClone(object){ let obj=new Object(); if(object instanceof Object){ // 说明是对象 for(let attr in object){ if(object.hasOwnProperty(attr)){ // 过滤基本类型值 if(typeof object[attr]!='object'||object[attr]==null){ obj[attr]=object[attr]; }else{ obj[attr]=deepClone(object[attr]); } } } } return obj; } let obj2=deepClone(obj); obj.b=1; console.log(obj,obj2);
注意,这个函数是存在问题的,由于这个函数只能处理纯对象类型,也就是说属性中包含数组的对象该方法是没法处理的。get
下面这里有一个方法是stackoverflow
上的答案,兼容了数组与对象的string
function clone(obj) { var copy; // Handle the 3 simple types, and null or undefined if (null == obj || "object" != typeof obj) return obj; // Handle Date if (obj instanceof Date) { copy = new Date(); copy.setTime(obj.getTime()); return copy; } // Handle Array if (obj instanceof Array) { copy = []; for (var i = 0, len = obj.length; i < len; i++) { copy[i] = clone(obj[i]); } return copy; } // Handle Object if (obj instanceof Object) { copy = {}; for (var attr in obj) { if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]); } return copy; } throw new Error("Unable to copy obj! Its type isn't supported."); }
还有一种比较抖机灵的作法就是io
var cloneOfA = JSON.parse(JSON.stringify(a));
这种作法也是能够实现深复制,可是因为JSON.stringify()
方法在遇到undefined
值时会省略对应的属性,因此这个方法不太推荐使用,存在问题。console
基于jQ的作法是这样的function
var copiedObject = jQuery.extend({}, originalObject) // shallow copy浅复制 var copiedObject = jQuery.extend(true, {}, originalObject) // deep copy深复制