src/services/clone.js
/**
* The service to clone complex objects, including Map.
* @method clone
* @param {T} obj - Object or Primitives to clone.
* @return {T}
*/
export function clone(obj, map = new Map()) {
// Primitives are immutable, no need to clone them.
if (Object(obj) !== obj) {
return obj;
}
else if (map.has(obj)) {
// Cyclic reference handling
return map.get(obj);
}
else {
let result = Array.isArray(obj)
? []
: obj.constructor && obj.constructor()
? obj.constructor()
: Object.create(obj);
if (Object(result) !== result) {
map.set(obj, obj);
result = obj;
}
else {
map.set(obj, result);
}
if (obj instanceof Map) {
return Array.from(obj, ([key, val]) => result.set(key, _toTail(val, map)))[0];
}
else {
return Object.assign(result, ...Object.keys(obj).map(key => ({ [key]: _toTail(obj[key], map) })));
}
}
}
/**
* @method _toTail
* @param {T} obj - Object or Primitives to clone.
* @param {any} map
* @return {T}
* @private
*/
function _toTail(obj, map) {
return clone(obj, map);
}
//Copyright (c) 2017 Alex Tranchenko. All rights reserved.