forked from jonschlinkert/clone-deep
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
77 lines (68 loc) · 1.87 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
'use strict';
/**
* Module dependenices
*/
const clone = require('shallow-clone');
const typeOf = require('kind-of');
const isPlainObject = require('is-plain-object');
const isSubset = require('is-subset');
const defaultFilter = {}
function cloneDeep(val, filter = defaultFilter, instanceClone = true, pkey = '') {
switch (typeOf(val)) {
case 'object':
return cloneObjectDeep(val, filter, instanceClone, pkey);
case 'array':
return cloneArrayDeep(val, filter, instanceClone, pkey);
default: {
return clone(val);
}
}
}
function cloneObjectDeep(val, filter, instanceClone, pkey) {
if (typeof instanceClone === 'function') {
return instanceClone(val);
}
if (instanceClone || isPlainObject(val)) {
const res = new val.constructor();
for (let key in val) {
const npkey = pkey === '' ? key : `${pkey}.${key}`;
const result = cloneDeep(val[key], filter, instanceClone, npkey);
let cloning = true;
if (filter.key === npkey) {
if (typeOf(result) === 'object' || typeOf(result) === 'array') {
cloning = isSubset(result, filter.value);
} else {
cloning = filter.value === result;
}
}
if (cloning) res[key] = result;
}
return res;
}
return val;
}
function cloneArrayDeep(val, filter, instanceClone, pkey) {
const res = [];
const npkey = `${pkey}[]`;
let ix = 0;
for (let i = 0; i < val.length; i++) {
const result = cloneDeep(val[i], filter, instanceClone, npkey);
let cloning = true;
if (filter.key === npkey) {
if (typeOf(result) === 'object' || typeOf(result) === 'array') {
cloning = isSubset(result, filter.value);
} else {
cloning = filter.value === result;
}
}
if (cloning) {
res[ix] = result;
ix++;
}
}
return res;
}
/**
* Expose `cloneDeep`
*/
module.exports = cloneDeep;