他日面试官的询问仍在我耳边游荡,今日特此记录学习
简单数组的深拷贝
1.for 循环
let arr=[1,2,3,4,5]
let arr1=copyArr(arr)
function copyArr(arr){
let arr2=[]
for(let i=0;i<arr.length;i++){
res.push(arr[i])
}
return res
}
2.slice方法
将原数组抽离出来形成新的数组
let arr=[1,2,3,4,5]
let arr1=arr.slice(0)
console.log(arr1)
//已经完成深拷贝
3.concat方法
连接多个数组从而形成新的数组
let arr=[1,2,3,4,5]
let arr1=arr.concat()
console.log(arr1)
4.es6扩展运算符实现数组的深拷贝
let arr=[1,2,3,4,5]
let arr1=[...arr]
console.log(arr1)
复杂数组的深拷贝
简单对象的深拷贝
1.for循环
let obj={
name:'xiaoming',
age:'12',
job:'doctor'
}
let obj1=copyObj(obj)
function copyObj(obj){
let res={}
for(let key in obj){
res[key]=obj[key]
}
}
2.json方式
let obj={
name:'xiaoming',
age:'12',
job:'doctor'
}
let obj1=JSON.parse(JSON.stringify(obj))
3.扩展运算符实现
let obj={
name:'xiaoming',
age:'12',
job:'doctor'
}
let obj2={...obj}
复杂对象的深拷贝
//复杂对象深拷贝的方法
function deepClone(initalObj,finalObj){
let obj=finalObj || {};
for(let i in initalObj){
// 防止出现相互引用对象导致的死循环 如initialObj.a=initialObj的情况
let pop=initalObj[i]
if(prop===obj){
continue
}
if(typeof prop==='object'){
obj[i]=(prop.constructor===Array)?[] :Object.create(prop)
}
else{
obj[i]=prop
}
}
return obj
}
function deepClone(obj, hash = new WeakMap()) {
if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
// 可能是对象或者普通的值 如果是函数的话是不需要深拷贝
if (typeof obj !== "object") return obj;
// 是对象的话就要进行深拷贝
if (hash.get(obj)) return hash.get(obj);
let cloneObj = new obj.constructor();
// 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
// 实现一个递归拷贝
cloneObj[key] = deepClone(obj[key], hash);
}
}
return cloneObj;
}
let obj = { name: 1, address: { x: 100 } };
obj.o = obj; // 对象存在循环引用的情况
let d = deepClone(obj);
obj.address.x = 200;
console.log(d);