對(duì)象的深拷貝和淺拷貝
//拷貝出來的結(jié)果 和以前沒關(guān)系 叫深拷貝
let school = { name: "王星星", age: 10 };
let my = { address: "回龍觀" };
let newObj = { ...school, ...my };
console.log(newObj);//{ name: '王星星', age: 10, address: '回龍觀' }
console.log(school)//{ name: '王星星', age: 10 }
newObj.age=20;//
console.log(newObj)//{ name: '王星星', age: 20, address: '回龍觀' }
console.log(school)//{ name: '王星星', age: 10 }
//...如果用的是多層對(duì)象 那就是淺拷貝
let school = { name: "王星星", age: 10 ,a:{b:2}};
let my = { address: "回龍觀" };
let newObj = { ...school, ...my };
console.log(newObj);//
console.log(school)//
newObj.a.b=20;//
console.log(newObj)//
console.log(school)//
如何 實(shí)現(xiàn)一個(gè)深拷貝 遞歸拷貝
1、外部庫(kù) lodash =>cloneDeep
2县钥、自實(shí)現(xiàn)
// 1) 怎么判斷數(shù)據(jù)的類型
// typeof object Array
// Object.prototype.toString.call()
// instanceof 可以判斷類型 判斷是誰的實(shí)例
// constructor 構(gòu)造函數(shù)
const deepClone = (value ,hash = new WeakMap) => {
if(value == null) return value; // 排除掉null 和undefine 的情況
if(typeof value !== 'object') return value; // 這里包含了函數(shù)類型
if(value instanceof RegExp) return new RegExp(value);
if(value instanceof Date) return new Date(value);
// .....
// 拷貝的人可能是一個(gè)對(duì)象 或者是一個(gè)數(shù)組 (循環(huán)) for in
let instance = new value.constructor; // 根據(jù)當(dāng)前屬性構(gòu)造一個(gè)新的實(shí)例
if(hash.has(value)){ // 先去hash中查看一下是否存在過 椭坚,如果存在就把以前拷貝的返回去
return hash.get(value); // 返回已經(jīng)拷貝的結(jié)果
}
hash.set(value,instance);// 沒放過就放進(jìn)去
// 用一個(gè)對(duì)象來記憶
for(let key in value){ // 一層
if(value.hasOwnProperty(key)){ // 將hash 繼續(xù)向下傳遞 保證這次拷貝能拿到以前拷貝的結(jié)果
instance[key] = deepClone(value[key],hash); // 產(chǎn)生的就是一個(gè)新的拷貝后的結(jié)果
}// 過濾掉原型鏈上的屬性
}
return instance
};
let school = {
name: "老肥",
age: 10,
a: { b: {c:45} },
fn: () => {},
c: undefined,
reg: /\d+/
};
let obj1 = deepClone(school);
obj1.a.b.c="王菲"
console.log(obj1);
console.log(school)