From 801cf47b350de2e4d587cd768020f790174d32cb Mon Sep 17 00:00:00 2001 From: ihengshuai Date: Sun, 10 Sep 2023 20:59:29 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/article/2019/js-copy.md | 41 +++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/article/2019/js-copy.md b/docs/article/2019/js-copy.md index fb6d8c55f..892912960 100644 --- a/docs/article/2019/js-copy.md +++ b/docs/article/2019/js-copy.md @@ -216,22 +216,33 @@ console.log(arr, arr4); 递归方法实现深度克隆原理:遍历对象、数组直到里边都是基本数据类型,然后再去复制,就是深度拷贝 -```js -function deepCopy(target, origin) { - target = target || {}; - let toStr = Object.prototype.toString, - arrStr = "[object Array]"; - for (let prop in origin) { - if (origin[prop] !== "null" && typeof origin[prop] == "object") { - toStr.call(origin[prop]) == arrStr - ? (target[prop] = []) - : (target[prop] = {}); - deepCopy(target[prop], origin[prop]); - } else { - target[prop] = origin[prop]; +```ts +function deepCopy(from: any, map: any = new Map()) { + const isObject = (obj: any): obj is Object => + Object.prototype.toString.call(obj) === "[object Object]" || + Object.prototype.toString.call(obj) === "[object Array]"; + + if (!isObject(from)) return from; + let res: any = Array.isArray(from) ? [] : {}; + + // 有缓存时不用递归,解决循环引用问题 + if (map.get(from)) res = map.get(from); + else { + // 缓存当前对象 + map.set(from, res); + for (const key of [ + ...Object.keys(from), + ...Object.getOwnPropertySymbols(from), + ]) { + const val = from[key]; + if (isObject(val)) { + res[key] = deepCopy(val, map); + } else { + res[key] = val; + } } } - return target; + return res; } ``` @@ -243,7 +254,7 @@ let a = { say: function() {}, m: Symbol(1) }; -const b = deepCopy({}, a) +const b = deepCopy(a) b.age = 12 b.arr[1] = 4 b.m = Symbol(2)