UNPKG

fenzhi-utils

Version:

分值前端项目的js函数库

103 lines (94 loc) 2.63 kB
/** * 深度克隆函数(包含函数、原型链、数组、循环引用,Symbol、Map、Set等) * @param {*} obj * @param {*} [hash=new WeakMap()] * @return {*} */ /** // 测试一: let obj = { str: 'hello world', num: 123, bool: true, nul: null, und: undefined, arr: [1, 2, 3], obj: { a: 1, b: 2, c: 3 }, func: function () { console.log('hello world'); }, sym: Symbol('hello'), map: new Map([ ['name', 'Tom'], ['age', 18], ]), set: new Set([1, 2, 3]), }; obj.loop = obj; // 循环引用 let cloneObj = CustomDeepClone(obj); console.log(cloneObj); obj.str = 'AIGC'; console.log(cloneObj); cloneObj.str = 'WEBAI'; console.log(cloneObj); console.log(obj); // 测试二: let arr1 = [{ a: 6 }, { a: 7 }]; let arr2 = CustomDeepClone(arr1); arr1[0].a = 8; arr2[0].a = 9; console.log(arr1);// [{ a: 8 }, { a: 7 }] console.log(arr2);// [{ a: 9 }, { a: 7 }] */ export function CustomDeepClone(obj, hash = new WeakMap()) { if ( Object(obj) !== obj || obj instanceof Function || obj instanceof RegExp || obj instanceof Error || obj instanceof Date ) { return obj; } if (hash.has(obj)) { return hash.get(obj); } let result; try { result = new obj.constructor(); } catch (e) { result = Object.create(Object.getPrototypeOf(obj)); } hash.set(obj, result); if (obj instanceof Map) { Array.from(obj, ([key, val]) => result.set(deepClone(key, hash), deepClone(val, hash)) ); } else if (obj instanceof Set) { Array.from(obj, (key) => result.add(deepClone(key, hash))); } else if (Array.isArray(obj)) { result = obj.map((item) => deepClone(item, hash)); } else { result = Object.getOwnPropertyNames(obj).reduce((acc, key) => { const descriptor = Object.getOwnPropertyDescriptor(obj, key); if ( descriptor.value !== undefined && typeof descriptor.value !== 'function' ) { descriptor.value = deepClone(descriptor.value, hash); } else if (descriptor.get || descriptor.set) { descriptor.get = deepClone(descriptor.get, hash); descriptor.set = deepClone(descriptor.set, hash); } Object.defineProperty(acc, key, descriptor); return acc; }, result); Object.setPrototypeOf(result, deepClone(Object.getPrototypeOf(obj), hash)); } if (obj instanceof Map) { Object.setPrototypeOf(result, Map.prototype); } else if (obj instanceof Set) { Object.setPrototypeOf(result, Set.prototype); } return result; }