Home Reference Source Repository

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.