屡见不鲜的题目了,今天尝试分别实现一个深拷贝和浅拷贝。
先上点开胃小菜的吧---浅拷贝:
浅拷贝的方法其实有很多,比如直接赋值给一个变量、Object.assign({},obj)、展开运算符{...obj}等,这边还是自己手写代码实现。
function shallowClone(obj){
if (!obj || typeof obj !== 'object' || obj == null) {
return obj;
}
let res;
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
res[key] = obj[key];
}
}
return res;
}
下面是深拷贝: 浅拷贝+递归。 了解:Object.getOwnPropertySymbols()、 WeakMap
function (obj, hash = new WeakMap()) {
if (!obj || typeof obj !== 'object' || obj == null) {
return obj;
}
if (hash.has(obj)) return hash.get(obj); // 读取缓存
let res = Array.isArray(obj) ? [] : {};
hash.set(obj, res); // 设置缓存
// ------------------------ 对Symbol类型进行深拷贝
let symbols = Object.getOwnPropertySymbols(obj);
if (symbols.length) {
symbols.forEach((sym) => {
if (typeof obj[sym] === 'object' && obj[sym] !== null) {
res[sym] = this.deepClone(obj[sym], hash);
} else {
res[sym] = obj[sym];
}
});
}
// ------------------
for (const key in obj) {
if (Object.hasOwnProperty.call(obj, key)) {
// 添加 数据类型判断
if (typeof obj[key] === 'object' && obj[key] !== null) {
// 引用值
res[key] = this.deepClone(obj[key], hash);
} else {
// 原始值
res[key] = obj[key];
}
}
}
return res;
};
可以对重复代码进行提取优化。 如有错误,欢迎评论指出。谢谢!