8000 Fix cloneDeep with circularly dependent Sets/Maps. [closes #3122] · lodash/lodash@b8c719d · GitHub
[go: up one dir, main page]

Skip to content

Commit b8c719d

Browse files
committed
Fix cloneDeep with circularly dependent Sets/Maps. [closes #3122]
1 parent d8e069c commit b8c719d

File tree

1 file changed

+21
-62
lines changed

1 file changed

+21
-62
lines changed

lodash.js

Lines changed: 21 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -451,34 +451,6 @@
451451

452452
/*--------------------------------------------------------------------------*/
453453

454-
/**
455-
* Adds the key-value `pair` to `map`.
456-
*
457-
* @private
458-
* @param {Object} map The map to modify.
459-
* @param {Array} pair The key-value pair to add.
460-
* @returns {Object} Returns `map`.
461-
*/
462-
function addMapEntry(map, pair) {
463-
// Don't return `map.set` because it's not chainable in IE 11.
464-
map.set(pair[0], pair[1]);
465-
return map;
466-
}
467-
468-
/**
469-
* Adds `value` to `set`.
470-
*
471-
* @private
472-
* @param {Object} set The set to modify.
473-
* @param {*} value The value to add.
474-
* @returns {Object} Returns `set`.
475-
*/
476-
function addSetEntry(set, value) {
477-
// Don't return `set.add` because it's not chainable in IE 11.
478-
set.add(value);
479-
return set;
480-
}
481-
482454
/**
483455
* A faster alternative to `Function#apply`, this function invokes `func`
484456
* with the `this` binding of `thisArg` and the arguments of `args`.
@@ -2691,7 +2663,7 @@
26912663
if (!cloneableTags[tag]) {
26922664
return object ? value : {};
26932665
}
2694-
result = initCloneByTag(value, tag, baseClone, isDeep);
2666+
result = initCloneByTag(value, tag, isDeep);
26952667
}
26962668
}
26972669
// Check for circular references and return its corresponding clone.
@@ -2702,6 +2674,22 @@
27022674
}
27032675
stack.set(value, result);
27042676

2677+
if (isSet(value)) {
2678+
value.forEach(function(subValue) {
2679+
result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
2680+
});
2681+
2682+
return result;
2683+
}
2684+
2685+
if (isMap(value)) {
2686+
value.forEach(function(subValue, key) {
2687+
result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
2688+
});
2689+
2690+
return result;
2691+
}
2692+
27052693
var keysFunc = isFull
27062694
? (isFlat ? getAllKeysIn : getAllKeys)
27072695
: (isFlat ? keysIn : keys);
@@ -4565,20 +4553,6 @@
45654553
return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
45664554
}
45674555

4568-
/**
4569-
* Creates a clone of `map`.
4570-
*
4571-
* @private
4572-
* @param {Object} map The map to clone.
4573-
* @param {Function} cloneFunc The function to clone values.
4574-
* @param {boolean} [isDeep] Specify a deep clone.
4575-
* @returns {Object} Returns the cloned map.
4576-
*/
4577-
function cloneMap(map, isDeep, cloneFunc) {
4578-
var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG) : mapToArray(map);
4579-
return arrayReduce(array, addMapEntry, new map.constructor);
4580-
}
4581-
45824556
/**
45834557
* Creates a clone of `regexp`.
45844558
*
@@ -4592,20 +4566,6 @@
45924566
return result;
45934567
}
45944568

4595-
/**
4596-
* Creates a clone of `set`.
4597-
*
4598-
* @private
4599-
* @param {Object} set The set to clone.
4600-
* @param {Function} cloneFunc The function to clone values.
4601-
* @param {boolean} [isDeep] Specify a deep clone.
4602-
* @returns {Object} Returns the cloned set.
4603-
*/
4604-
function cloneSet(set, isDeep, cloneFunc) {
4605-
var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG) : setToArray(set);
4606-
return arrayReduce(array, addSetEntry, new set.constructor);
4607-
}
4608-
46094569
/**
46104570
* Creates a clone of the `symbol` object.
46114571
*
@@ -6227,16 +6187,15 @@
62276187
* Initializes an object clone based on its `toStringTag`.
62286188
*
62296189
* **Note:** This function only supports cloning values with tags of
6230-
* `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
6190+
* `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
62316191
*
62326192
* @private
62336193
* @param {Object} object The object to clone.
62346194
* @param {string} tag The `toStringTag` of the object to clone.
6235-
* @param {Function} cloneFunc The function to clone values.
62366195
* @param {boolean} [isDeep] Specify a deep clone.
62376196
* @returns {Object} Returns the initialized clone.
62386197
*/
6239-
function initCloneByTag(object, tag, cloneFunc, isDeep) {
6198+
function initCloneByTag(object, tag, isDeep) {
62406199
var Ctor = object.constructor;
62416200
switch (tag) {
62426201
case arrayBufferTag:
@@ -6255,7 +6214,7 @@
62556214
return cloneTypedArray(object, isDeep);
62566215

62576216
case mapTag:
6258-
return cloneMap(object, isDeep, cloneFunc);
6217+
return new Ctor;
62596218

62606219
case numberTag:
62616220
case stringTag:
@@ -6265,7 +6224,7 @@
62656224
return cloneRegExp(object);
62666225

62676226
case setTag:
6268-
return cloneSet(object, isDeep, cloneFunc);
6227+
return new Ctor;
62696228

62706229
case symbolTag:
62716230
return cloneSymbol(object);

0 commit comments

Comments
 (0)
0