UNPKG

@jsbits/deep-clone

Version:

Performs a deep cloning of an object own properties and symbols, with loosy or exact behavior.

192 lines (191 loc) 6.07 kB
/* @jsbits/deep-clone @author aMarCruz @version 1.1.1 UMD+ES5 @license MIT */ /* eslint-disable */ ;(function(root, factory) { if (typeof define == 'function' && define.amd) { define([], factory) } else if (typeof module == 'object' && module.exports) { module.exports = factory() } else { ((root.$ || root.jQuery || {}).jsbits || root.jsbits || (root.jsbits={})).deepClone = factory() } })(typeof self !== 'undefined' ? self : this, function () { "use strict"; 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) { // istanbul ignore next var _keys = exact ? Object.getOwnPropertyNames : Object.keys; var _getSymbols = Object.getOwnPropertySymbols; // istanbul ignore next: until we can test IE11 if (!_getSymbols) { return _keys; } // istanbul ignore if: until we can test IE11 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); }; // istanbul ignore else if (!_nodejs || _nodejs >= 5) { return _getTag; } // istanbul ignore next 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)); var deepClone = function _deepClone(value, exact) { return exact ? exactClone(value) : looseClone(value); }; return deepClone; });