在jsvaScript中,简单值是通过直复制来进行赋值传递的,而引用类型是通过引用赋值来进行复制传递的。
var a = 2;
var b = a;
b = 3;
console.log(a) //2
console.log(b) //3
var arr1 = [1,2,3];
var arr2 = arr1;
arr2.push(4);
console.log(arr1); //[1,2,3,4]
console.log(arr2); //[1,2,3,4]
第一种情况就是简单值得复制传递,a和b分别在两个内存中,b=a知识吧a的值复制给b,改变b的值不会影响a的值。
第二种情况是引用类型的复制,arr2 = arr1是将arr1的地址复制给arr2,两个数组指向同一片内存区域,所以改变arr2的值也会改变arr1的值。是数组的浅拷贝。
下面来看看什么是数组的深拷贝
var a = [1,2,3];
var b = a.slice(0);
var c = a.concat();
b.push(4);
c.push(5);
console.log(a); //[1,2,3]
console.log(b); //[1,2,3,4]
console.log(c); //[1,2,3,5]
对象的浅拷贝
function easyClone(Obj) {
var objNew = {};
for ( var i in Obj) {
objNew[i] = Obj[i];
}
return objNew;
}
其实就是将每个原对象的属性和值复制到新对象上去,当然我们也可以使用Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象,同时Object.assign() 也是浅拷贝。
浅拷贝因为没有递归循环检查对象的每个值是否是对象,而是直接进行了赋值,所以如果某个值是对象的时候就会出现问题,所以在一般情况下我们需要用深拷贝来进行备份。
对象的深拷贝
最简单的深拷贝
var b = JSON.parse(JSON.stringify(a))
但是这种深拷贝有一定的局限性,第一:无法复制函数,第二:原形链没了,对象就是object,所属的类没了。
其实简单的深拷贝只需要我们递归调用浅拷贝就可以了:
function deepCopy(obj) {
var objNew = objNew || {};
for (var i in obj) {
if (typeof p[i] === 'object') {
objNew[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(obj[i], objNew[i]);
} else {
objNew[i] = obj[i];
}
}
return objNew;
}