- 浅克隆
(1)对象的浅克隆:
<script>
//=>浅克隆:只复制对象或者数组的第一级内容
//=>深克隆:克隆后数组的每一级都和原始数组没有关联
//那么请说出,浅克隆都怎么去实现,如何实现深度克隆
let obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/
};
let arr = [10, [100, 200], {
x: 10,
y: 20
}];
//第一种浅克隆
let newObj={...obj};
//第二种浅克隆
let newObj=Object.assign({},obj);
//第三种
//for in在遍历对象的时候,遍历是当前对象可枚举(列举)的属性
//私有属性(除一些特殊的内置属性是不可枚举的)
//公有属性(大部分都是不可枚举的,但是自己在类原型上扩展的是可枚举的)
//由下面的(2)也说明在遍历的过程中,很可能遍历到共有的属性方法,所以for in 循环的时候,我们需要判断是否为私有的
let newObj={};
for(let key in obj){
if(!obj.hasOwnProperty(key)) break;
newObj[key]=obj[key];
}
console.log(newObj,obj)
</script>
for in 和 for of
自定义类的遍历
(2)数组的浅克隆
<script>
let arr = [10, [100, 200], {
x: 10,
y: 20
}];
//第一种
let newArr=[...arr];
//第二种
let newArr=Object.assign([],arr);
//第三种
let newArr=arr.map(item=>item);
//第四种
let newArr=arr.slice();
//第五种
let newArr=arr.concat([]);
console.log(newArr,arr); //newArr==arr false newArr[1]==arr[1] true
</script>
- 深克隆
(1)
方案1:整体变为字符串,在重新变为对象,这样浏览器会重新开辟全套的内存空间存储信息。 JSON.stringify / JSON.parse。
此方案存在BUG:把对象中的某些属性值变为字符串,会存在问题。
正则变为{}
日期对象变为日期字符串
Symbol/BigInt/function/undefined 等会消失
所以这种方案只适用于数据中只有“number/string/boolean/null/普通对象/数组对象”等内容的时候。
对象:
<script>
let obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/
};
let newObj=JSON.parse(JSON.stringify(obj));
</script>
数组:
<script>
let arr = [10, [100, 200], {
x: 10,
y: 20
}];
let newArr=JSON.parse(JSON.stringify(arr));
console.log(newArr,arr);
</script>
(2)方案2:一层层遍历
<script>
let obj = {
a: 100,
b: [10, 20, 30],
c: {
x: 10
},
d: /^\d+$/,
e:Symbol('AA'),
f:new Date(),
g:function(){},
h:undefined,
i:null
};
obj.name=obj;
function cloneDeep(obj){
let type=typeof obj;
//如果传递的不是对象类型,直接返回对应的值(基本类型/函数/Symbol/BigInt)
if(obj===null) return null;
if(type!=="object" && type!=="function") return obj;
//结果是正则或者日期函数,我们创建一个值类似但是不同实例的结果出来
if(/^(RegExp|Date)$/i.test(constructor.name)) return new constructor(obj);
//获取当前值的构造函数:获知它的类型
let constructor=obj.constructor;
//创建对象的新实例:新数组或者新对象
let clone=new constructor;
for(let key in obj){
if(!obj.hasOwnProperty(key)) break;
//为了避免对象中的某个属性用的还是对象,导致的循环嵌套(死递归)
if(obj===obj[name]){
clone[key]=obj[key];
break;
}
clone[key]=cloneDeep(obj[key]);
}
return clone;
}
// let newObj=JSON.parse(JSON.stringify(obj));
</script>