Skip to content

Commit 21759d3

Browse files
committed
ref: deepClone & deepMerge
1 parent 1e19e9d commit 21759d3

File tree

2 files changed

+46
-35
lines changed

2 files changed

+46
-35
lines changed

uview-ui/libs/function/deepClone.js

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
11
// 判断arr是否为一个数组,返回一个bool值
2-
function isArray (arr) {
3-
return Object.prototype.toString.call(arr) === '[object Array]';
2+
function isArray(arr) {
3+
return Object.prototype.toString.call(arr) === '[object Array]';
44
}
55

66
// 深度克隆
7-
function deepClone (obj) {
8-
// 对常见的“非”值,直接返回原来值
9-
if([null, undefined, NaN, false].includes(obj)) return obj;
10-
if(typeof obj !== "object" && typeof obj !== 'function') {
11-
//原始类型直接返回
12-
return obj;
13-
}
14-
var o = isArray(obj) ? [] : {};
15-
for(let i in obj) {
16-
if(obj.hasOwnProperty(i)){
17-
o[i] = typeof obj[i] === "object" ? deepClone(obj[i]) : obj[i];
18-
}
19-
}
20-
return o;
7+
function deepClone(obj, cache = new WeakMap()) {
8+
if (obj === null || typeof obj !== 'object') return obj;
9+
if (cache.has(obj)) return cache.get(obj);
10+
let clone;
11+
if (obj instanceof Date) {
12+
clone = new Date(obj.getTime());
13+
} else if (obj instanceof RegExp) {
14+
clone = new RegExp(obj);
15+
} else if (obj instanceof Map) {
16+
clone = new Map(Array.from(obj, ([key, value]) => [key, deepClone(value, cache)]));
17+
} else if (obj instanceof Set) {
18+
clone = new Set(Array.from(obj, value => deepClone(value, cache)));
19+
} else if (Array.isArray(obj)) {
20+
clone = obj.map(value => deepClone(value, cache));
21+
} else if (Object.prototype.toString.call(obj) === '[object Object]') {
22+
clone = Object.create(Object.getPrototypeOf(obj));
23+
cache.set(obj, clone);
24+
for (const [key, value] of Object.entries(obj)) {
25+
clone[key] = deepClone(value, cache);
26+
}
27+
} else {
28+
clone = Object.assign({}, obj);
29+
}
30+
cache.set(obj, clone);
31+
return clone;
2132
}
2233

34+
2335
export default deepClone;

uview-ui/libs/function/deepMerge.js

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,27 @@ import deepClone from "./deepClone";
33
// JS对象深度合并
44
function deepMerge(target = {}, source = {}) {
55
target = deepClone(target);
6-
if (typeof target !== 'object' || typeof source !== 'object') return false;
7-
for (var prop in source) {
6+
if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) return target;
7+
const merged = Array.isArray(target) ? target.slice() : Object.assign({}, target);
8+
for (const prop in source) {
89
if (!source.hasOwnProperty(prop)) continue;
9-
if (prop in target) {
10-
if (typeof target[prop] !== 'object') {
11-
target[prop] = source[prop];
12-
} else {
13-
if (typeof source[prop] !== 'object') {
14-
target[prop] = source[prop];
15-
} else {
16-
if (target[prop].concat && source[prop].concat) {
17-
target[prop] = target[prop].concat(source[prop]);
18-
} else {
19-
target[prop] = deepMerge(target[prop], source[prop]);
20-
}
21-
}
22-
}
10+
const sourceValue = source[prop];
11+
const targetValue = merged[prop];
12+
if (sourceValue instanceof Date) {
13+
merged[prop] = new Date(sourceValue);
14+
} else if (sourceValue instanceof RegExp) {
15+
merged[prop] = new RegExp(sourceValue);
16+
} else if (sourceValue instanceof Map) {
17+
merged[prop] = new Map(sourceValue);
18+
} else if (sourceValue instanceof Set) {
19+
merged[prop] = new Set(sourceValue);
20+
} else if (typeof sourceValue === 'object' && sourceValue !== null) {
21+
merged[prop] = deepMerge(targetValue, sourceValue);
2322
} else {
24-
target[prop] = source[prop];
23+
merged[prop] = sourceValue;
2524
}
2625
}
27-
return target;
26+
return merged;
2827
}
2928

30-
export default deepMerge;
29+
export default deepMerge;

0 commit comments

Comments
 (0)