浅拷贝
定义: 对一个对象进行拷贝时,仅仅拷贝对象的引用进行拷贝,但是拷贝对象和源对象还是引用同一份实体
* 其中一个对象的改变都会影响到另一个对象
var obj1 = { x:1, y:2 }
var obj2 = obj1;
obj2.x = 100;
console.log(obj1, obj2); //{x: 100, y: 2} {x: 100, y: 2}
深拷贝
定义: 拷贝一个对象时,不仅仅把对象的引用进行复制,还把该对象引用的值也一起拷贝
* 源对象与拷贝对象互相独立,其中任何一个对象的改动都不会对另外一个对象造成影响
第一种: for in
var obj1 = {x: 1, y: 2};
var obj2 = {}; // 定义一个空对象
for(var key in obj1) {
obj2[key] = obj1[key]
}
obj2.x = 100;
console.log(obj1, obj2); //{x: 1, y: 2} {x: 100, y: 2}
第二种: object.assign()
var obj1 = { x: 1, y: 2}
var obj2 = Object.assign({}, obj1);
obj2.x = 100;
console.log(obj1, obj2); //{x: 1, y: 2} {x: 100, y: 2}
第三种: ...运算符
var obj1 = {x: 1, y: 2}
var obj2 = {...obj1};
obj2.x = 100;
console.log(obj1, obj2); //{x: 1, y: 2} {x: 100, y: 2}
第四种: JSON.parse(JSON.stringify())
var obj1 = { x: 1, y: 2}
var obj2 = JSON.parse(JSON.stringify(obj1));
ob2.x = 100;
console.log(obj1, obj2); //{x: 1, y: 2} {x: 100, y: 2}
除了第四种深拷贝JSON.parse(JSON.stringify()),其他方式只能做一层拷贝。 如果考虑深层的嵌套关系那么就需要用深拷贝了
怎么实现深拷贝:利用的是递归
function deepCopy(obj2){
/*
* 把一个对象递归拷贝给另外一个对象
* 源对象与拷贝后的对象没有引用关系,实现克隆
*/
var obj = isArray(obj2)?[]:{};
// 判断被拷贝对象是数组还是对象,如果不考虑数组的话,会出现一些问题,
// 如果被拷贝对象里面有数组对象的话,会把数组变为对象,
// 如果传进来是一个数组的话,就让它是一个数组的,是一个对象就是一个对象的
// 取出obj2的所有属性,如果当前拷贝的数据还是一个对象的话,
// 那么继续调用,deepCopy进行二次拷贝,递归
for(var property in obj2){
if(isObject(obj2[property])){
obj[property] = deepCopy(obj2[property])
}else{
obj[property] = obj2[property]
}
}
return obj;
}
// 判断一个值是不是数组
function isArray(val){
return Object.prototype.toString.call(val) === '[object Array]';
// 这里直接用Es6中的Array.isArray()方法判断是不是数组也是可以的,但是上面那种是一些标准库的常见用法
}
// 判断是不是对象
function isObject(val){
return typeof val ==='object' && val !== null;
}
var obj1 = {x: 1, y: 2, z: { a:3, b: 4}}
var obj2 = deepCopy(obj1);
obj2.x = 100;
obj2.z.a = 200;
console.log(obj1, obj2);
如有问题请大家指点迷津,谢谢!