UNPKG

z-util-page

Version:
133 lines (132 loc) 3.49 kB
let cacheMap = new WeakMap(); const typeHandleMap = { 'Object': function (value) { let cloneTarget = new value.constructor(); forEach(Object.keys(value), function (val, key) { cloneTarget[val] = realDeepClone(value[val]); }); return cloneTarget; }, 'Array': function (value) { let cloneTarget = []; forEach(value, function (val, key) { cloneTarget[key] = realDeepClone(value[key]); }); return cloneTarget; }, 'Set': function (value) { let cloneTarget = new value.constructor(); value.forEach(function (val) { cloneTarget.add(realDeepClone(val)); }); return cloneTarget; }, 'Map': function (value) { let cloneTarget = new value.constructor(); value.forEach(function (val, key) { cloneTarget.set(realDeepClone(key), realDeepClone(val)); }); return cloneTarget; }, 'Symbol': function (value) { return Object(Symbol.prototype.valueOf.call(value)); }, 'HTMLElement': function (value) { return value.cloneNode(true); }, 'Error': function (value) { return new value.constructor(value.message); } }; const baseTypeList = ['boolean', 'number', 'string', 'undefined', "function", "symbol", 'Null', "Math", "Json", "Global"]; const simpleTypeList = ["Boolean", "Number", 'String', 'Date', "Regexp"]; /** * while循环 * @param list 待循环列表 * @param handle 循环行为 */ function forEach(list, handle) { let index = -1; let length = list.length; while (++index < length) { handle(list[index], index); } } /** * 循环深拷贝 * @param value 待克隆值 * @returns 克隆值 */ function realDeepClone(value) { let type = typeof value; if (type === 'object') type = getType(value); if (value instanceof HTMLElement) type = 'HTMLElement'; if (baseTypeList.includes(type)) return value; else if (simpleTypeList.includes(type)) return new value.constructor(value); let cloneTarget = cacheMap.get(value); if (cloneTarget === undefined) { let handle = typeHandleMap[type]; if (handle) cloneTarget = handle(value); else cloneTarget = value; cacheMap.set(value, cloneTarget); } return cloneTarget; } /** * 获取数据类型 * @category 辅助函数 * @example * ```ts * const type = getType('你好'); * type === 'String'; * ``` * @param value 任意值 * @returns 类型字符串, 如'String'、'Map'等 */ export function getType(value) { try { return Object.prototype.toString.call(value).match(/\[.+\s(.+)\]/)[1]; } catch (e) { throw (e); } } /** * 深拷贝 * @category 辅助函数 * @example * ```ts * let newValue = deepClone({ * a: '身体和心灵,总有一个在路上。', * b: { * c: new Date(), * d: [1, 3, 4], * e: Symbol(), * a: null, * b: undefined, * f: { * a: 1, * b: true, * } * }, * c: document.createElement('div'), * d: new RegExp(/\d+/ig), * e: new Error('错误'), * f: function () { * console.log('身体和心灵,总有一个在路上。'); * } * ``` * @param value 待克隆值 * @returns 克隆值 */ export function deepClone(value) { const result = realDeepClone(value); cacheMap = new WeakMap(); return result; }