Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80742 views
1
var arrayCopy = require('./arrayCopy'),
2
arrayEach = require('./arrayEach'),
3
baseAssign = require('./baseAssign'),
4
baseForOwn = require('./baseForOwn'),
5
initCloneArray = require('./initCloneArray'),
6
initCloneByTag = require('./initCloneByTag'),
7
initCloneObject = require('./initCloneObject'),
8
isArray = require('../lang/isArray'),
9
isObject = require('../lang/isObject');
10
11
/** `Object#toString` result references. */
12
var argsTag = '[object Arguments]',
13
arrayTag = '[object Array]',
14
boolTag = '[object Boolean]',
15
dateTag = '[object Date]',
16
errorTag = '[object Error]',
17
funcTag = '[object Function]',
18
mapTag = '[object Map]',
19
numberTag = '[object Number]',
20
objectTag = '[object Object]',
21
regexpTag = '[object RegExp]',
22
setTag = '[object Set]',
23
stringTag = '[object String]',
24
weakMapTag = '[object WeakMap]';
25
26
var arrayBufferTag = '[object ArrayBuffer]',
27
float32Tag = '[object Float32Array]',
28
float64Tag = '[object Float64Array]',
29
int8Tag = '[object Int8Array]',
30
int16Tag = '[object Int16Array]',
31
int32Tag = '[object Int32Array]',
32
uint8Tag = '[object Uint8Array]',
33
uint8ClampedTag = '[object Uint8ClampedArray]',
34
uint16Tag = '[object Uint16Array]',
35
uint32Tag = '[object Uint32Array]';
36
37
/** Used to identify `toStringTag` values supported by `_.clone`. */
38
var cloneableTags = {};
39
cloneableTags[argsTag] = cloneableTags[arrayTag] =
40
cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
41
cloneableTags[dateTag] = cloneableTags[float32Tag] =
42
cloneableTags[float64Tag] = cloneableTags[int8Tag] =
43
cloneableTags[int16Tag] = cloneableTags[int32Tag] =
44
cloneableTags[numberTag] = cloneableTags[objectTag] =
45
cloneableTags[regexpTag] = cloneableTags[stringTag] =
46
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =
47
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
48
cloneableTags[errorTag] = cloneableTags[funcTag] =
49
cloneableTags[mapTag] = cloneableTags[setTag] =
50
cloneableTags[weakMapTag] = false;
51
52
/** Used for native method references. */
53
var objectProto = Object.prototype;
54
55
/**
56
* Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring)
57
* of values.
58
*/
59
var objToString = objectProto.toString;
60
61
/**
62
* The base implementation of `_.clone` without support for argument juggling
63
* and `this` binding `customizer` functions.
64
*
65
* @private
66
* @param {*} value The value to clone.
67
* @param {boolean} [isDeep] Specify a deep clone.
68
* @param {Function} [customizer] The function to customize cloning values.
69
* @param {string} [key] The key of `value`.
70
* @param {Object} [object] The object `value` belongs to.
71
* @param {Array} [stackA=[]] Tracks traversed source objects.
72
* @param {Array} [stackB=[]] Associates clones with source counterparts.
73
* @returns {*} Returns the cloned value.
74
*/
75
function baseClone(value, isDeep, customizer, key, object, stackA, stackB) {
76
var result;
77
if (customizer) {
78
result = object ? customizer(value, key, object) : customizer(value);
79
}
80
if (result !== undefined) {
81
return result;
82
}
83
if (!isObject(value)) {
84
return value;
85
}
86
var isArr = isArray(value);
87
if (isArr) {
88
result = initCloneArray(value);
89
if (!isDeep) {
90
return arrayCopy(value, result);
91
}
92
} else {
93
var tag = objToString.call(value),
94
isFunc = tag == funcTag;
95
96
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
97
result = initCloneObject(isFunc ? {} : value);
98
if (!isDeep) {
99
return baseAssign(result, value);
100
}
101
} else {
102
return cloneableTags[tag]
103
? initCloneByTag(value, tag, isDeep)
104
: (object ? value : {});
105
}
106
}
107
// Check for circular references and return corresponding clone.
108
stackA || (stackA = []);
109
stackB || (stackB = []);
110
111
var length = stackA.length;
112
while (length--) {
113
if (stackA[length] == value) {
114
return stackB[length];
115
}
116
}
117
// Add the source value to the stack of traversed objects and associate it with its clone.
118
stackA.push(value);
119
stackB.push(result);
120
121
// Recursively populate clone (susceptible to call stack limits).
122
(isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
123
result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB);
124
});
125
return result;
126
}
127
128
module.exports = baseClone;
129
130