Skip to content

Instantly share code, notes, and snippets.

@zorgick
Forked from wjx0820/deepClone.js
Created January 3, 2022 20:34
Show Gist options
  • Save zorgick/c511d15371333106d210d05b034cf7e5 to your computer and use it in GitHub Desktop.
Save zorgick/c511d15371333106d210d05b034cf7e5 to your computer and use it in GitHub Desktop.
深拷贝 deepClone
// 通过 typeof 来查看每种数据类型的描述
// [undefined, null, true, '', 0, Symbol(), {}].map(it => typeof it)
// ["undefined", "object", "boolean", "string", "number", "symbol", "object"]
function clone(obj) {
// 添加一个 WeakMap 来记录已经拷贝过的对象,如果当前对象已经被拷贝过,那么直接从 WeakMap 中取出,否则重新创建一个对象并加入 WeakMap 中
// ES6 推出的 WeakMap 对象,该对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的
let map = new WeakMap();
function deep(data) {
let result = {};
// 在遍历 Object 类型数据时,我们需要把 Symbol 数据类型也考虑进来,所以不能通过 Object.keys 获取键名或 for...in 方式遍历,而是通过 getOwnPropertyNames 和 getOwnPropertySymbols 函数将键名组合成数组,然后进行遍历。
const keys = [
...Object.getOwnPropertyNames(data),
...Object.getOwnPropertySymbols(data),
];
// 对于键数组长度为 0 的非 Object 类型的数据可直接返回
if (!keys.length) return data;
const exist = map.get(data)
if (exist) return exist
map.set(data, result)
keys.forEach((key) => {
let item = data[key];
// 判断 item 为 object 且不为 null,因为 typeof null 是 object
if (typeof item === "object" && item) {
result[key] = deep(item);
} else {
result[key] = item;
}
});
return result;
}
return deep(obj)
}
// test
const a = {name:'bob', obj: {age:12,sex:"male"}}
const b = clone(a)
console.log(b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment