@jsbits/deep-clone
Version:
Performs a deep cloning of an object own properties and symbols, with loosy or exact behavior.
203 lines (200 loc) • 6.21 kB
JavaScript
/*
@jsbits/deep-clone
@author aMarCruz
@version 1.1.1 ESM+ES5
@license MIT
*/
/* eslint-disable */
var _a;
var _nodejs = (function () {
var g = typeof global === 'object' && global;
var m = g && g.process &&
typeof g.Buffer === 'function' && /^v?(\d+)/.exec(g.process.version);
return (m && m[1]) | 0;
})();
var _OP = Object.prototype;
var _toString = _OP.toString;
var _ownKeys = typeof Reflect === 'object' &&
typeof Reflect.ownKeys === 'function' && Reflect.ownKeys;
var clonable = {
Date: 1 ,
RegExp: 1 ,
String: 1 ,
Number: 1 ,
Boolean: 1 ,
Float32Array: 1 ,
Float64Array: 1 ,
Int8Array: 1 ,
Int16Array: 1 ,
Int32Array: 1 ,
Uint8Array: 1 ,
Uint8ClampedArray: 1 ,
Uint16Array: 1 ,
Uint32Array: 1 ,
Array: 2 ,
ArrayBuffer: 3 ,
SharedArrayBuffer: 3 ,
DataView: 4 ,
Error: 6 ,
Map: 5 ,
Set: 5 ,
Arguments: 7 ,
Atomics: 8 ,
JSON: 8 ,
Math: 8 ,
Promise: 8 ,
WeakMap: 8 ,
WeakSet: 8 ,
XMLHttpRequest: 8 ,
};
var arrayLike = [
'Array',
'String',
'Float32Array',
'Float64Array',
'Int8Array',
'Int16Array',
'Int32Array',
'Uint8Array',
'Uint8ClampedArray',
'Uint16Array',
'Uint32Array',
];
var getKeyGetter = function (exact) {
var _keys = exact ? Object.getOwnPropertyNames : Object.keys;
var _getSymbols = Object.getOwnPropertySymbols;
if (!_getSymbols) {
return _keys;
}
if (exact) {
return function (obj) { return _keys(obj).concat(_getSymbols(obj)); };
}
var _isEnum = _OP.propertyIsEnumerable;
return function (obj) {
var objkeys = _keys(obj);
var symbols = _getSymbols(obj);
for (var i = 0; i < symbols.length; i++) {
if (_isEnum.call(obj, symbols[i])) {
objkeys.push(symbols[i]);
}
}
return objkeys;
};
};
var getKeysFac = function (exact) {
var _filtIdx = function (prop) { return prop !== '0' && (prop | 0) <= 0 && prop !== 'length'; };
var _getKeys = exact && _ownKeys || getKeyGetter(exact);
return function (obj, type) {
var objkeys = _getKeys(obj);
return ~arrayLike.indexOf(type) ? objkeys.filter(_filtIdx) : objkeys;
};
};
var cloneMapOrSet = function (src, fn, type) {
var dest = new src.constructor();
var cb = type === 'Set'
? function (v) { this.add(fn(v)); }
: function (v, k) { this.set(fn(k), fn(v)); };
src.forEach(cb, dest);
return dest;
};
var cloneDataView = function (src) {
var buffer = src.buffer.slice(0);
return new src.constructor(buffer, src.byteOffset, src.byteLength);
};
var cloneError = function (src) {
var err = new src.constructor(src.message);
return Object.defineProperty(err, 'stack', {
value: src.stack, configurable: true, writable: true,
});
};
var cloneArguments = function (src) {
var args = Object.create(null);
return Object.defineProperty(args, 'length', {
value: src.length, configurable: true, writable: true,
});
};
var cloneArray = function (src, fn) { return src.map(fn); };
var cloneFn = (_a = {},
_a[8 ] = function (obj) { return obj; },
_a[7 ] = cloneArguments,
_a[2 ] = cloneArray,
_a[3 ] = function (obj) { return obj.slice(0); },
_a[4 ] = cloneDataView,
_a[6 ] = cloneError,
_a[5 ] = cloneMapOrSet,
_a);
var createObject = function (obj, type, fn) {
var cloneType = clonable[type];
if (cloneType === 1 ) {
return obj.slice && _nodejs && Buffer.isBuffer(obj)
? obj.slice(0)
: new obj.constructor(obj.valueOf());
}
if (cloneFn[cloneType]) {
return cloneFn[cloneType](obj, fn, type);
}
return type.lastIndexOf(' Iterator', type.length - 9) > -1
? obj : Object.create(Object.getPrototypeOf(obj));
};
var getObjectType = (function () {
var _getTag = function (obj) { return _toString.call(obj).slice(8, -1); };
if (!_nodejs || _nodejs >= 5) {
return _getTag;
}
return function (obj) {
var tag = _getTag(obj);
return tag === 'Object' && obj.constructor && obj.constructor.name === 'Promise'
? 'Promise' : tag;
};
})();
var cloneFac = function (getKeys) {
var _clone = function _clone(obj) {
if (!obj || typeof obj !== 'object') {
return obj;
}
var type = getObjectType(obj);
var clone = createObject(obj, type, _clone);
var props = getKeys(obj, type);
for (var i = 0; i < props.length; i++) {
var prop = props[i];
var desc = Object.getOwnPropertyDescriptor(obj, prop);
if (desc.value !== undefined) {
desc.value = _clone(obj[prop]);
}
Object.defineProperty(clone, prop, desc);
}
return clone;
};
return _clone;
};
var looseClone = cloneFac(getKeysFac(false));
var exactClone = cloneFac(getKeysFac(true));
/**
* Performs a deep cloning of an object own properties and symbols, preserving
* its prototype.
*
* By default `cloneObject` works in "loosy mode", where it clones only
* the object _enumerable_ properties and symbols.
*
* To enable the "exact mode" and clone all, pass `true` in the second parameter.
*
* Both modes retain all the attributes of the copied properties (enumerable,
* configurable, writable) and correctly transfer the `get` and/or `set`
* methods, although these, like the other function-type values,
* _are copied by reference_.
*
* Try to limit the usage of this function to POJOs, as this function does not
* work for objects with constructor that requires parameters (other than
* the most JS built-in Objects), nor objects with recursive references.
*
* @template T
* @param {T} value Value to clone, mostly an object or array.
* @param {boolean} [exact=false] If `true`, also clone the non-enumerable properties
* @returns {T} The cloned object or value.
* @since 1.0.0
*/
var deepClone = function _deepClone(value, exact) {
return exact ? exactClone(value) : looseClone(value);
};
export default deepClone;
//# sourceMappingURL=index.js.map