对象复制,就是以一个对象为基础生成一个一模一样的对象。但是在javascript中,使用简单的赋值语句所实现的是原对象的一个引用,对其中任何一个对象属性方法的改变,都将会影响另一个的属性方法.
仅仅复制原对象的各个属性,而不复制原对象属性中引用的其他对象,导致新对象和原对象的这些属性引用的是一个地址。
也就是所,假如源对象的属性值是一个指向对象的引用,它也只拷贝那个引用值。
var arr = ['old', 1, true, null, undefined];
var newArr = arr.concat();
var newArr2 = arr.slice();
function shadowCopy(src) {
var dst = src instanceof Array?[]:{};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
var obj = {
a:2,
b:{c:3}
};
var shadowObj = shadowCopy(obj);
shadowObj.b == obj.b; //true
可以看到,对于浅复制,新对象和原对象引用的是同一个对象。
var copy = Object.assign({}, obj);
Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象身上。
在浅复制的基础上,把要复制的对象所引用的对象也都复制了一遍。因此要用递归来改进上面的浅复制。
function deepCopy(src){
var dst = {};
for(prop in src){
if(src.hasOwnProperty(prop)){
if(typeof src[prop] == "object"){
dst[prop] = deepCopy(src[prop]);
}else{
dst[prop] = src[prop];
}
}
}
return dst;
}
var obj = {
a:2,
b:{
c:3,
d:{
e:4
}
}
};
var deepObj = deepCopy(obj);
deepObj.b == obj.b; //false
deepObj.b.d == obj.b.d; //false
可以看到深复制不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。
要实现深复制还有许多其他的方法:
var cloneObj = JSON.parse(JSON.stringify(obj));
jQuery.extend([deep], target, object1, [objectN])
此方法用于用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
第一个deep参数则指定是深拷贝还是浅拷贝。若为true则为深拷贝。
function clone(src){
var target;
if(typeof src != "object"){
return src;
}
target = Array.isArray(src)?[]:{};
for(var prop in src){
if(Object.prototype.hasOwnProperty.call(src,prop)){
target[prop] = clone(src[prop]);
}
}
return target;
}