@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
JavaScript
/*
@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;
});