Spaces:
Runtime error
Runtime error
var Stack = require('./_Stack'), | |
arrayEach = require('./_arrayEach'), | |
assignValue = require('./_assignValue'), | |
baseAssign = require('./_baseAssign'), | |
baseAssignIn = require('./_baseAssignIn'), | |
cloneBuffer = require('./_cloneBuffer'), | |
copyArray = require('./_copyArray'), | |
copySymbols = require('./_copySymbols'), | |
copySymbolsIn = require('./_copySymbolsIn'), | |
getAllKeys = require('./_getAllKeys'), | |
getAllKeysIn = require('./_getAllKeysIn'), | |
getTag = require('./_getTag'), | |
initCloneArray = require('./_initCloneArray'), | |
initCloneByTag = require('./_initCloneByTag'), | |
initCloneObject = require('./_initCloneObject'), | |
isArray = require('./isArray'), | |
isBuffer = require('./isBuffer'), | |
isMap = require('./isMap'), | |
isObject = require('./isObject'), | |
isSet = require('./isSet'), | |
keys = require('./keys'), | |
keysIn = require('./keysIn'); | |
/** Used to compose bitmasks for cloning. */ | |
var CLONE_DEEP_FLAG = 1, | |
CLONE_FLAT_FLAG = 2, | |
CLONE_SYMBOLS_FLAG = 4; | |
/** `Object#toString` result references. */ | |
var argsTag = '[object Arguments]', | |
arrayTag = '[object Array]', | |
boolTag = '[object Boolean]', | |
dateTag = '[object Date]', | |
errorTag = '[object Error]', | |
funcTag = '[object Function]', | |
genTag = '[object GeneratorFunction]', | |
mapTag = '[object Map]', | |
numberTag = '[object Number]', | |
objectTag = '[object Object]', | |
regexpTag = '[object RegExp]', | |
setTag = '[object Set]', | |
stringTag = '[object String]', | |
symbolTag = '[object Symbol]', | |
weakMapTag = '[object WeakMap]'; | |
var arrayBufferTag = '[object ArrayBuffer]', | |
dataViewTag = '[object DataView]', | |
float32Tag = '[object Float32Array]', | |
float64Tag = '[object Float64Array]', | |
int8Tag = '[object Int8Array]', | |
int16Tag = '[object Int16Array]', | |
int32Tag = '[object Int32Array]', | |
uint8Tag = '[object Uint8Array]', | |
uint8ClampedTag = '[object Uint8ClampedArray]', | |
uint16Tag = '[object Uint16Array]', | |
uint32Tag = '[object Uint32Array]'; | |
/** Used to identify `toStringTag` values supported by `_.clone`. */ | |
var cloneableTags = {}; | |
cloneableTags[argsTag] = cloneableTags[arrayTag] = | |
cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = | |
cloneableTags[boolTag] = cloneableTags[dateTag] = | |
cloneableTags[float32Tag] = cloneableTags[float64Tag] = | |
cloneableTags[int8Tag] = cloneableTags[int16Tag] = | |
cloneableTags[int32Tag] = cloneableTags[mapTag] = | |
cloneableTags[numberTag] = cloneableTags[objectTag] = | |
cloneableTags[regexpTag] = cloneableTags[setTag] = | |
cloneableTags[stringTag] = cloneableTags[symbolTag] = | |
cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = | |
cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; | |
cloneableTags[errorTag] = cloneableTags[funcTag] = | |
cloneableTags[weakMapTag] = false; | |
/** | |
* The base implementation of `_.clone` and `_.cloneDeep` which tracks | |
* traversed objects. | |
* | |
* @private | |
* @param {*} value The value to clone. | |
* @param {boolean} bitmask The bitmask flags. | |
* 1 - Deep clone | |
* 2 - Flatten inherited properties | |
* 4 - Clone symbols | |
* @param {Function} [customizer] The function to customize cloning. | |
* @param {string} [key] The key of `value`. | |
* @param {Object} [object] The parent object of `value`. | |
* @param {Object} [stack] Tracks traversed objects and their clone counterparts. | |
* @returns {*} Returns the cloned value. | |
*/ | |
function baseClone(value, bitmask, customizer, key, object, stack) { | |
var result, | |
isDeep = bitmask & CLONE_DEEP_FLAG, | |
isFlat = bitmask & CLONE_FLAT_FLAG, | |
isFull = bitmask & CLONE_SYMBOLS_FLAG; | |
if (customizer) { | |
result = object ? customizer(value, key, object, stack) : customizer(value); | |
} | |
if (result !== undefined) { | |
return result; | |
} | |
if (!isObject(value)) { | |
return value; | |
} | |
var isArr = isArray(value); | |
if (isArr) { | |
result = initCloneArray(value); | |
if (!isDeep) { | |
return copyArray(value, result); | |
} | |
} else { | |
var tag = getTag(value), | |
isFunc = tag == funcTag || tag == genTag; | |
if (isBuffer(value)) { | |
return cloneBuffer(value, isDeep); | |
} | |
if (tag == objectTag || tag == argsTag || (isFunc && !object)) { | |
result = (isFlat || isFunc) ? {} : initCloneObject(value); | |
if (!isDeep) { | |
return isFlat | |
? copySymbolsIn(value, baseAssignIn(result, value)) | |
: copySymbols(value, baseAssign(result, value)); | |
} | |
} else { | |
if (!cloneableTags[tag]) { | |
return object ? value : {}; | |
} | |
result = initCloneByTag(value, tag, isDeep); | |
} | |
} | |
// Check for circular references and return its corresponding clone. | |
stack || (stack = new Stack); | |
var stacked = stack.get(value); | |
if (stacked) { | |
return stacked; | |
} | |
stack.set(value, result); | |
if (isSet(value)) { | |
value.forEach(function(subValue) { | |
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); | |
}); | |
} else if (isMap(value)) { | |
value.forEach(function(subValue, key) { | |
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); | |
}); | |
} | |
var keysFunc = isFull | |
? (isFlat ? getAllKeysIn : getAllKeys) | |
: (isFlat ? keysIn : keys); | |
var props = isArr ? undefined : keysFunc(value); | |
arrayEach(props || value, function(subValue, key) { | |
if (props) { | |
key = subValue; | |
subValue = value[key]; | |
} | |
// Recursively populate clone (susceptible to call stack limits). | |
assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack)); | |
}); | |
return result; | |
} | |
module.exports = baseClone; | |