@newdash/newdash
Version:
javascript/typescript utility library
228 lines (227 loc) • 9.26 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-nocheck
const isArray_1 = __importDefault(require("../isArray"));
const isBuffer_1 = __importDefault(require("../isBuffer"));
const isMap_1 = __importDefault(require("../isMap"));
const isObject_1 = __importDefault(require("../isObject"));
const isSet_1 = __importDefault(require("../isSet"));
const keys_1 = __importDefault(require("../keys"));
const keysIn_1 = __importDefault(require("../keysIn"));
const arrayEach_1 = __importDefault(require("./arrayEach"));
const assignValue_1 = __importDefault(require("./assignValue"));
const baseAssign_1 = __importDefault(require("./baseAssign"));
const baseAssignIn_1 = __importDefault(require("./baseAssignIn"));
const cloneArrayBuffer_1 = __importDefault(require("./cloneArrayBuffer"));
const cloneBuffer_1 = __importDefault(require("./cloneBuffer"));
const cloneDataView_1 = __importDefault(require("./cloneDataView"));
const cloneRegExp_1 = __importDefault(require("./cloneRegExp"));
const cloneSymbol_1 = __importDefault(require("./cloneSymbol"));
const cloneTypedArray_1 = __importDefault(require("./cloneTypedArray"));
const copyArray_1 = __importDefault(require("./copyArray"));
const copySymbols_1 = __importDefault(require("./copySymbols"));
const copySymbolsIn_1 = __importDefault(require("./copySymbolsIn"));
const getAllKeys_1 = __importDefault(require("./getAllKeys"));
const getAllKeysIn_1 = __importDefault(require("./getAllKeysIn"));
const getTag_1 = __importDefault(require("./getTag"));
const GLOBAL_1 = require("./GLOBAL");
const initCloneObject_1 = __importDefault(require("./initCloneObject"));
const Stack_1 = __importDefault(require("./Stack"));
/** Used to compose bitmasks for cloning. */
const CLONE_DEEP_FLAG = 1;
const CLONE_FLAT_FLAG = 2;
const CLONE_SYMBOLS_FLAG = 4;
/** `Object#toString` result references. */
const argsTag = '[object Arguments]';
const arrayTag = '[object Array]';
const boolTag = '[object Boolean]';
const dateTag = '[object Date]';
const errorTag = '[object Error]';
const mapTag = '[object Map]';
const numberTag = '[object Number]';
const objectTag = '[object Object]';
const regexpTag = '[object RegExp]';
const setTag = '[object Set]';
const stringTag = '[object String]';
const symbolTag = '[object Symbol]';
const weakMapTag = '[object WeakMap]';
const arrayBufferTag = '[object ArrayBuffer]';
const dataViewTag = '[object DataView]';
const float32Tag = '[object Float32Array]';
const float64Tag = '[object Float64Array]';
const int8Tag = '[object Int8Array]';
const int16Tag = '[object Int16Array]';
const int32Tag = '[object Int32Array]';
const uint8Tag = '[object Uint8Array]';
const uint8ClampedTag = '[object Uint8ClampedArray]';
const uint16Tag = '[object Uint16Array]';
const uint32Tag = '[object Uint32Array]';
/** Used to identify `toStringTag` values supported by `clone`. */
const 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[weakMapTag] = false;
/** Used to check objects for own properties. */
const hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Initializes an object clone based on its `toStringTag`.
*
* **Note:** This function only supports cloning values with tags of
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
*
* @private
* @param {Object} object The object to clone.
* @param {string} tag The `toStringTag` of the object to clone.
* @param {boolean} [isDeep] Specify a deep clone.
* @returns {Object} Returns the initialized clone.
*/
function initCloneByTag(object, tag, isDeep) {
const Ctor = object.constructor;
switch (tag) {
case arrayBufferTag:
return (0, cloneArrayBuffer_1.default)(object);
case boolTag:
case dateTag:
return new Ctor(+object);
case dataViewTag:
return (0, cloneDataView_1.default)(object, isDeep);
case float32Tag:
case float64Tag:
case int8Tag:
case int16Tag:
case int32Tag:
case uint8Tag:
case uint8ClampedTag:
case uint16Tag:
case uint32Tag:
return (0, cloneTypedArray_1.default)(object, isDeep);
case mapTag:
return new Ctor;
case numberTag:
case stringTag:
return new Ctor(object);
case regexpTag:
return (0, cloneRegExp_1.default)(object);
case setTag:
return new Ctor;
case symbolTag:
return (0, cloneSymbol_1.default)(object);
}
}
/**
* Initializes an array clone.
*
* @private
* @param {Array} array The array to clone.
* @returns {Array} Returns the initialized clone.
*/
function initCloneArray(array) {
const { length } = array;
const result = new array.constructor(length);
// Add properties assigned by `RegExp#exec`.
if (length && typeof array[0] === 'string' && hasOwnProperty.call(array, 'index')) {
result.index = array.index;
result.input = array.input;
}
return result;
}
/**
* The base implementation of `clone` and `cloneDeep` which tracks
* traversed objects.
*
* @private
* @param value The value to clone.
* @param bitmask The bitmask flags.
* 1 - Deep clone
* 2 - Flatten inherited properties
* 4 - Clone symbols
* @param customizer The function to customize cloning.
* @param key The key of `value`.
* @param object The parent object of `value`.
* @param 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 (!(0, isObject_1.default)(value)) {
return value;
}
var isArr = (0, isArray_1.default)(value);
if (isArr) {
result = initCloneArray(value);
if (!isDeep) {
return (0, copyArray_1.default)(value, result);
}
}
else {
var tag = (0, getTag_1.default)(value), isFunc = tag == GLOBAL_1.funcTag || tag == GLOBAL_1.genTag;
if ((0, isBuffer_1.default)(value)) {
// @ts-ignore
return (0, cloneBuffer_1.default)(value, isDeep);
}
if (tag == objectTag || tag == argsTag || (isFunc && !object)) {
result = (isFlat || isFunc) ? {} : (0, initCloneObject_1.default)(value);
if (!isDeep) {
return isFlat
? (0, copySymbolsIn_1.default)(value, (0, baseAssignIn_1.default)(result, value))
: (0, copySymbols_1.default)(value, (0, baseAssign_1.default)(result, value));
}
}
else {
if (!cloneableTags[tag]) {
return object ? value : {};
}
result = initCloneByTag(value, tag, isDeep);
}
}
// Check for circular references and return its corresponding clone.
// @ts-ignore
stack || (stack = new Stack_1.default);
var stacked = stack.get(value);
if (stacked) {
return stacked;
}
stack.set(value, result);
if ((0, isSet_1.default)(value)) {
value.forEach(function (subValue) {
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
});
}
else if ((0, isMap_1.default)(value)) {
value.forEach(function (subValue, key) {
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
});
}
var keysFunc = isFull
? (isFlat ? getAllKeysIn_1.default : getAllKeys_1.default)
: (isFlat ? keysIn_1.default : keys_1.default);
var props = isArr ? undefined : keysFunc(value);
(0, arrayEach_1.default)(props || value, function (subValue, key) {
if (props) {
key = subValue;
subValue = value[key];
}
// Recursively populate clone (susceptible to call stack limits).
(0, assignValue_1.default)(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
});
return result;
}
exports.default = baseClone;