平时我们在做开发时,由于对象和数组都是引用类型。所以不能直接用“=”来复制一个对象 开发中我们用的比较多的浅拷贝复制或者数组的方法就是扩展符
浅拷贝复制对象或者数组
let a={name:'111'};
复制对象a
我们可以用
let b = {...a}
数组也是这个道理
let c=[1,2,3]
let d=[...c];
深拷贝复制一个对象
let a={name:'111',props:{age:21,height:180}}
复制对象a
let b = JSON.parse(JSON.stringify(a));
但是它还是有很大缺陷的,比如拷贝其他引用类型、拷贝函数、循环引用等情况。
我们可以写一个简单的函数
浅拷贝函数
function clone(target) {
let cloneTarget = {};
for (const key in target) {
cloneTarget[key] = target[key];
}
return cloneTarget;
};
深拷贝函数
function isObject(obj) {
return typeof obj === 'object' && obj != null;
}
function deepCopy(source, hash = new WeakMap()) {
// 判断如果参数不是一个对象,返回该参数
if (!isObject(source)) return source;
if (hash.has(source)) return hash.get(source); // 如果拷贝过该对象,则直接返回该对象
// 判断参数是对象还是数组来初始化返回值
let res = Array.isArray(source) ? [] : {};
hash.set(source, res); // 哈希表添加新对象
// 循环参数对象的key
for (let key in source) {
// 如果该key属于参数对象本身
if (Object.prototype.hasOwnProperty.call(source, key)) {
// 如果该key的value值是对象,递归调用深拷贝方法进行拷贝
if (isObject(source[key])) {
res[key] = deepCopy(source[key], hash);
} else {
// 如果该key的value值不是对象,则把参数对象key的value值赋给返回值的key
res[key] = source[key];
}
}
}
// 返回返回值
return res;
};