function cloneDeep(value, customizer, thisArg) {
  return typeof customizer == 'function'
    ? baseClone(value, true, bindCallback(customizer, thisArg, 3))
    : baseClone(value, true);
}
Creates a deep clone of `value`. If `customizer` is provided it's invoked
to produce the cloned values. If `customizer` returns `undefined` cloning
is handled by the method instead. The `customizer` is bound to `thisArg`
and invoked with up to three argument; (value [, index|key, object]).

**Note:** This method is loosely based on the
[structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm).
The enumerable properties of `arguments` objects and objects created by
constructors other than `Object` are cloned to plain `Object` objects. An
empty object is returned for uncloneable values such as functions, DOM nodes,
Maps, Sets, and WeakMaps.

@static
@memberOf _
@category Lang
@param {*} value The value to deep clone.
@param {Function} [customizer] The function to customize cloning values.
@param {*} [thisArg] The `this` binding of `customizer`.
@returns {*} Returns the deep cloned value.
@example

var users = [
  { 'user': 'barney' },
  { 'user': 'fred' }
];

var deep = _.cloneDeep(users);
deep[0] === users[0];
// => false

// using a customizer callback
var el = _.cloneDeep(document.body, function(value) {
  if (_.isElement(value)) {
    return value.cloneNode(true);
  }
});

el === document.body
// => false
el.nodeName
// => BODY
el.childNodes.length;
// => 20