Насколько я знаю, _.cloneDeepWith()
настройщик немного вводит в заблуждение.Настройщик должен обрабатывать только не объектные значения.Если он обрабатывает значения объекта, он также должен сам продолжить рекурсию.Например, вы можете видеть, что при вызове настройщика клонирование обрабатывается value.cloneNode(true)
.Как видите, в консоли отображается только body
.
const { cloneDeepWith, isObject } = _;
function customizer(value) {
console.log(value);
if (_.isElement(value)) {
return value.cloneNode(true);
}
}
var el = _.cloneDeepWith(document.body, customizer);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Однако, если вы просто настраиваете не объектные значения и возвращаете undefined
для значений объекта, который предлагает метод для их обработки (задокументировано в cloneDeep ), он повторяет все:
const { cloneDeepWith, isObject, isUndefined } = _;
const obj = {
a0: true,
b0: true,
c0: undefined,
obj1: {
a1: true,
b1: true,
c1: undefined
}
};
const result = cloneDeepWith(obj, v => {
console.log(v);
return isObject(v) ? undefined : 'custom value';
});
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Чтобы решить вашу проблему, вы можете использовать _.transform()
рекурсивно, чтобы принять все значения, которые не undefined
:
const { transform, isObject, isUndefined } = _;
const obj = {
a0: true,
b0: true,
c0: undefined,
obj1: {
a1: true,
b1: true,
c1: undefined
}
};
const cloneDeepWithoutUndefined = (obj) =>
transform(obj, (r, v, k) => {
if(isUndefined(v)) return;
r[k] = isObject(v) ? cloneDeepWithoutUndefined(v) : v;
});
const result = cloneDeepWithoutUndefined(obj);
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>