1.浅拷贝
如果要拷贝的属性为简单数据类型,则拷贝值,引用数据类型拷贝地址,简单来说就是只拷贝一层
实现浅拷贝的方式:
Object.assign(target,source)//把源对象拷贝到目标对象上slice()concat(){...}
写一个简单的吧
const shallowCopy = function(oldObj){
const newObj = {}
for(let i of oldObj){
//用hasOwnProperty来判断是否是自有属性
if(oldObj.hasOwnProperty(i)){
newObj[i] = oldObj[i]
}
}
return newObj
}
2.深拷贝
深拷贝会开辟一个新的栈,拷贝的对象属性与原来完全相同,但是由于对应着不同的地址,一个的更改不会影响到另一个
实现深拷贝的方法
JSON.stringify()- 各种库的方法,如lodash的
_.cloneDeep
再写一个深拷贝吧
const copy = function (oldObj, hash = new WeakMap()) {
//1.处理特殊类型
if (oldObj === null) return oldObj;
if (oldObj instanceof Date) return new Date(oldObj);
if (oldObj instanceof RegExp) return new RegExp(oldObj);
//2.处理数组和对象
if (typeof oldObj !== "object") return oldObj;
let newObj = Array.isArray(oldObj) ? [] : {};
//为了防止循环引用,我们可以额外开辟一个存储空间,,来存储当前对象和拷贝对象间的关系,
//当准备拷贝对象时,如果这个对象已经存储在map中了,如果拷贝过了就直接返回,没有就加入
if (hash.get(oldObj)) {
return hash.get(oldObj);
}
hash.set(oldObj, newObj);
//3.递归遍历对象
for (let i in oldObj) {
if (oldObj.hasOwnProperty(i)) {
newObj[i] = copy(oldObj[i], hash);
}
}
return newObj;
};
这里解释下为什么用WeakMap类型:
如果用map的话他是强引用类型这意味着只要 Map 对象存在,所有的键都会存在,不会被垃圾回收器回收。
WeakMap:对于键对象是弱引用,这意味着如果键对象没有被其他部分的代码所引用,它可能会被垃圾回收器回收,从而使得相应的键值对从 WeakMap 中删除。这样对内存更加友好