/**
* 浅拷贝和深拷贝是针对复杂数据类型的
* 浅拷贝可以通过扩展运算符{...}和Object.assgin来实现
* 对于复杂类型来说,浅拷贝后新对象和旧对象指向的是同一块内存地址
*/
let obj1 = {
name: 'lucy',
age:18,
hobbies:['reading','sing','draw']
}
let obj2=Object.assign({},obj1);
let obj3={...obj1};
obj1.hobbies.push('dance');
console.log(obj1); //{name:'lucy',age:18,hobbies:['reading','sing','draw','dance']}
console.log(obj2);//{name:'lucy',age:18,hobbies:['reading','sing','draw','dance']}
console.log(obj3); //{name:'lucy',age:18,hobbies:['reading','sing','draw','dance']}
/**
*深拷贝后的两个对象之间是相互隔离的,对一个对象的修改并不会影响到另外一个对象
*JSON.parse(JSON.stringify())的缺点是:
*对象的属性值是函数时,无法拷贝。
*原型链上的属性无法拷贝
*不能正确的处理 Date 类型的数据
*不能处理 RegExp
*会忽略 symbol
*会忽略 undefined
*/
let obj1 = {
name: 'lucy',
age:18,
hobbies:['reading','sing','draw']
}
let obj2=JSON.parse(JSON.stringify(obj1));
obj1.hobbies.push('dancing');
console.log(obj1);//{name:'lucy',age:18,hobbies:['reading','sing','draw','dancing']}
console.log(obj2);//{name:'lucy',age:18,hobbies:['reading','sing','draw']}
function deepClone(obj,hash=new WeakMap){
//如果是正则对象直接返回
if(obj instanceof RegExp) return new RegExp(obj);
//如果是日期对象也直接返回
if(obj instanceof Date) return new Date(obj);
//如果不是复杂数据类型直接返回
if(obj===null || typeof obj!=="object") return obj;
/*
* 如果obj是数组,那么obj.constructor=[Function:Array]
* 如果obj是对象,那么obj.constructor=[Function:object]
*/
let t=new obj.constructor();
hash.set(obj,t);
for(let key in obj){
//对象本身上存在这个键
if(obj.hasOwnProperty(key)){
//将这个键所对应的值重新进行深拷贝
t[key]=deepClone(obj[key],hash);
}
}
return t;
}