function cloneWithReplace(
obj,
replacers = {},
storeMap = new Map()
) {
if(storeMap.has(obj)) {
return storeMap.get(obj);
}
const type = typeof obj;
if(obj === null || (type !== 'object' && type !== 'function')) {
return obj;
}
let result;
if(type === 'function') {
result = function() {
return obj.apply(this, arguments);
};
try {
Object.defineProperties(result, {
name: Object.getOwnPropertyDescriptor(obj, 'name'),
length: Object.getOwnPropertyDescriptor(obj, 'length')
});
} catch {}
} else if(Array.isArray(obj)) {
result = obj.map(value => cloneWithReplace(value, replacers, storeMap));
storeMap.set(obj, result);
return result;
} else {
result = Object.setPrototypeOf({}, Object.getPrototypeOf(obj));
}
storeMap.set(obj, result);
for(const key of Object.getOwnPropertyNames(obj).concat(Object.getOwnPropertySymbols(obj))) {
if(typeof replacers[key] === 'function') {
result[key] = replacers[key](obj[key]);
} else {
result[key] = cloneWithReplace(obj[key], replacers, storeMap);
}
}
return result;
}
const data = {
key: ['value1', 'value2'],
find: {
key: 'key',
key2: [{
key12: 'value12',
key45: 'value 45',
value: 'some value'
}, {
key32: 'value122',
key33: 'value 435',
value: 'some value'
}, {
key56: 'value56',
key51: 'value 5111',
value: 'some value'
}]
},
key22: ['some', 'test', 'value'],
};