1 var Stack = require('./_Stack'),
2 arrayEach = require('./_arrayEach'),
3 assignValue = require('./_assignValue'),
4 baseAssign = require('./_baseAssign'),
5 baseForOwn = require('./_baseForOwn'),
6 cloneBuffer = require('./_cloneBuffer'),
7 copyArray = require('./_copyArray'),
8 copySymbols = require('./_copySymbols'),
9 getTag = require('./_getTag'),
10 initCloneArray = require('./_initCloneArray'),
11 initCloneByTag = require('./_initCloneByTag'),
12 initCloneObject = require('./_initCloneObject'),
13 isArray = require('./isArray'),
14 isBuffer = require('./isBuffer'),
15 isHostObject = require('./_isHostObject'),
16 isObject = require('./isObject');
18 /** `Object#toString` result references. */
19 var argsTag = '[object Arguments]',
20 arrayTag = '[object Array]',
21 boolTag = '[object Boolean]',
22 dateTag = '[object Date]',
23 errorTag = '[object Error]',
24 funcTag = '[object Function]',
25 genTag = '[object GeneratorFunction]',
26 mapTag = '[object Map]',
27 numberTag = '[object Number]',
28 objectTag = '[object Object]',
29 regexpTag = '[object RegExp]',
30 setTag = '[object Set]',
31 stringTag = '[object String]',
32 symbolTag = '[object Symbol]',
33 weakMapTag = '[object WeakMap]';
35 var arrayBufferTag = '[object ArrayBuffer]',
36 float32Tag = '[object Float32Array]',
37 float64Tag = '[object Float64Array]',
38 int8Tag = '[object Int8Array]',
39 int16Tag = '[object Int16Array]',
40 int32Tag = '[object Int32Array]',
41 uint8Tag = '[object Uint8Array]',
42 uint8ClampedTag = '[object Uint8ClampedArray]',
43 uint16Tag = '[object Uint16Array]',
44 uint32Tag = '[object Uint32Array]';
46 /** Used to identify `toStringTag` values supported by `_.clone`. */
47 var cloneableTags = {};
48 cloneableTags[argsTag] = cloneableTags[arrayTag] =
49 cloneableTags[arrayBufferTag] = cloneableTags[boolTag] =
50 cloneableTags[dateTag] = cloneableTags[float32Tag] =
51 cloneableTags[float64Tag] = cloneableTags[int8Tag] =
52 cloneableTags[int16Tag] = cloneableTags[int32Tag] =
53 cloneableTags[mapTag] = cloneableTags[numberTag] =
54 cloneableTags[objectTag] = cloneableTags[regexpTag] =
55 cloneableTags[setTag] = cloneableTags[stringTag] =
56 cloneableTags[symbolTag] = cloneableTags[uint8Tag] =
57 cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] =
58 cloneableTags[uint32Tag] = true;
59 cloneableTags[errorTag] = cloneableTags[funcTag] =
60 cloneableTags[weakMapTag] = false;
63 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
67 * @param {*} value The value to clone.
68 * @param {boolean} [isDeep] Specify a deep clone.
69 * @param {Function} [customizer] The function to customize cloning.
70 * @param {string} [key] The key of `value`.
71 * @param {Object} [object] The parent object of `value`.
72 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
73 * @returns {*} Returns the cloned value.
75 function baseClone(value, isDeep, customizer, key, object, stack) {
78 result = object ? customizer(value, key, object, stack) : customizer(value);
80 if (result !== undefined) {
83 if (!isObject(value)) {
86 var isArr = isArray(value);
88 result = initCloneArray(value);
90 return copyArray(value, result);
93 var tag = getTag(value),
94 isFunc = tag == funcTag || tag == genTag;
96 if (isBuffer(value)) {
97 return cloneBuffer(value, isDeep);
99 if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
100 if (isHostObject(value)) {
101 return object ? value : {};
103 result = initCloneObject(isFunc ? {} : value);
105 return copySymbols(value, baseAssign(result, value));
108 return cloneableTags[tag]
109 ? initCloneByTag(value, tag, isDeep)
110 : (object ? value : {});
113 // Check for circular references and return its corresponding clone.
114 stack || (stack = new Stack);
115 var stacked = stack.get(value);
119 stack.set(value, result);
121 // Recursively populate clone (susceptible to call stack limits).
122 (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) {
123 assignValue(result, key, baseClone(subValue, isDeep, customizer, key, value, stack));
125 return isArr ? result : copySymbols(value, result);
128 module.exports = baseClone;