Commit 21759d31 authored by 北桥's avatar 北桥

ref: deepClone & deepMerge

parent 1e19e9df
// 判断arr是否为一个数组,返回一个bool值 // 判断arr是否为一个数组,返回一个bool值
function isArray (arr) { function isArray(arr) {
return Object.prototype.toString.call(arr) === '[object Array]'; return Object.prototype.toString.call(arr) === '[object Array]';
} }
// 深度克隆 // 深度克隆
function deepClone (obj) { function deepClone(obj, cache = new WeakMap()) {
// 对常见的“非”值,直接返回原来值 if (obj === null || typeof obj !== 'object') return obj;
if([null, undefined, NaN, false].includes(obj)) return obj; if (cache.has(obj)) return cache.get(obj);
if(typeof obj !== "object" && typeof obj !== 'function') { let clone;
//原始类型直接返回 if (obj instanceof Date) {
return obj; clone = new Date(obj.getTime());
} } else if (obj instanceof RegExp) {
var o = isArray(obj) ? [] : {}; clone = new RegExp(obj);
for(let i in obj) { } else if (obj instanceof Map) {
if(obj.hasOwnProperty(i)){ clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)]));
o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i]; } else if (obj instanceof Set) {
} clone = new Set(Array.from(obj, value => deepClone(value, cache)));
} } else if (Array.isArray(obj)) {
return o; clone = obj.map(value => deepClone(value, cache));
} else if (Object.prototype.toString.call(obj) === '[object Object]') {
clone = Object.create(Object.getPrototypeOf(obj));
cache.set(obj, clone);
for (const [key, value] of Object.entries(obj)) {
clone[key] = deepClone(value, cache);
}
} else {
clone = Object.assign({}, obj);
}
cache.set(obj, clone);
return clone;
} }
export default deepClone; export default deepClone;
...@@ -3,28 +3,27 @@ import deepClone from "./deepClone"; ...@@ -3,28 +3,27 @@ import deepClone from "./deepClone";
// JS对象深度合并 // JS对象深度合并
function deepMerge(target = {}, source = {}) { function deepMerge(target = {}, source = {}) {
target = deepClone(target); target = deepClone(target);
if (typeof target !== 'object' || typeof source !== 'object') return false; if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target;
for (var prop in source) { const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target);
for (const prop in source) {
if (!source.hasOwnProperty(prop)) continue; if (!source.hasOwnProperty(prop)) continue;
if (prop in target) { const sourceValue = source[prop];
if (typeof target[prop] !== 'object') { const targetValue = merged[prop];
target[prop] = source[prop]; if (sourceValue instanceof Date) {
} else { merged[prop] = new Date(sourceValue);
if (typeof source[prop] !== 'object') { } else if (sourceValue instanceof RegExp) {
target[prop] = source[prop]; merged[prop] = new RegExp(sourceValue);
} else { } else if (sourceValue instanceof Map) {
if (target[prop].concat && source[prop].concat) { merged[prop] = new Map(sourceValue);
target[prop] = target[prop].concat(source[prop]); } else if (sourceValue instanceof Set) {
} else { merged[prop] = new Set(sourceValue);
target[prop] = deepMerge(target[prop], source[prop]); } else if (typeof sourceValue === 'object' && sourceValue !== null) {
} merged[prop] = deepMerge(targetValue, sourceValue);
}
}
} else { } else {
target[prop] = source[prop]; merged[prop] = sourceValue;
} }
} }
return target; return merged;
} }
export default deepMerge; export default deepMerge;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment