The task is to implement _.cloneDeep.
The boilerplate code
function cloneDeep(data) {
// your code here
}
cloneDeep is used for recursive deep copy. For primitive types, they are immutable, so they are returned as is
if(data === null || typeof data !== "object") {
return data;
}
For circular references, WeakMap cannot be cloned
if (seen.has(data)) {
return seen.get(data);
}
Special objects are handled explicitly because naive recursion breaks them. Dates need timestamp copy
if (data instanceof Date) {
return new Date(data.getTime());
}
RegExp needs patterns and flags
if (data instanceof RegExp) {
return new RegExp(data.source, data.flags);
}
Map needs to have their keys and values deep-cloned
if (data instanceof Map) {
const result = new Map();
seen.set(data, result);
data.forEach((value, key) => {
result.set(cloneDeep(key, seen), cloneDeep(value, seen));
});
return result;
}
Set values also need to be deep cloned
if (data instanceof Set) {
const result = new Set();
seen.set(data, result);
data.forEach(value => {
result.add(cloneDeep(value, seen));
});
return result;
}
For Arrays and Objects, preserve custom prototypes and class instances
const result = Array.isArray(data)
? []
: Object.create(Object.getPrototypeOf(data));
seen.set(data, result);
for (const key of Reflect.ownKeys(data)) {
result[key] = cloneDeep(data[key], seen);
}
return result;
The final code
function cloneDeep(data, seen = new WeakMap()) {
// your code here
if(data === null || typeof data !== "object") {
return data;
}
if(seen.has(data)) {
return seen.get(data);
}
if(data instanceof Date) {
return new Date(data.getTime());
}
if(data instanceof RegExp) {
return new RegExp(data.source, data.flags);
}
if(data instanceof Map) {
const result = new Map();
seen.set(data, result);
data.forEach((value, key) => {
result.set(cloneDeep(key, seen), cloneDeep(value, seen));
})
return result;
}
if(data instanceof Set) {
const result = new Set();
seen.set(data, result);
data.forEach(value => {
result.add(cloneDeep(value, seen));
})
return result;
}
const result = Array.isArray(data) ? [] : Object.create(Object.getPrototypeOf(data));
seen.set(data, result);
for(const key of Reflect.ownKeys(data)) {
result[key] = cloneDeep(data[key], seen);
}
return result;
}
That's all folks!
Top comments (0)