对一个对象或许数组这类援用范例的值举行复制能够分为浅复制和深复制,比方如许的一个对象
let obj={
a:1,
b:{
a:1,
b:2
},
c:3
}
很明显这个对象是存在两层的,obj[b]不是基础范例值,而是另一个对象。假如运用浅复制去拷贝这个对象的话,那末拷贝出来新的对象的b属性的值是本来对象b属性的援用地点,也就是说,假如转变源对象的b属性,新的对象也会受到影响,因为我们只运用浅复制拷贝了一层。
上面讲的就是浅复制,在现实运用中存在很严重的题目。所以我们平常复制对象都是用深复制,深复制不是简朴的复制一层,而是遍历全部对象,一直到获取到的值不是援用范例,而是基础范例的时刻才举行复制,如许就使得新的对象跟本来的对象完全是两个差别的对象了。
下面是我写的一个简朴的深复制函数
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);
注重,这个函数是存在题目的,因为这个函数只能处置惩罚纯对象范例,也就是说属性中包括数组的对象该要领是没法处置惩罚的。
下面这里有一个要领是stackoverflow
上的答案,兼容了数组与对象的
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.");
}
另有一种比较抖灵巧的做法就是
var cloneOfA = JSON.parse(JSON.stringify(a));
这类做法也是能够完成深复制,然则因为JSON.stringify()
要领在碰到undefined
值时会省略对应的属性,所以这个要领不太引荐运用,存在题目。
基于jQ的做法是如许的
var copiedObject = jQuery.extend({}, originalObject) // shallow copy浅复制
var copiedObject = jQuery.extend(true, {}, originalObject) // deep copy深复制