-
-
Save zorgick/c511d15371333106d210d05b034cf7e5 to your computer and use it in GitHub Desktop.
深拷贝 deepClone
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 通过 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