Skip to content

Instantly share code, notes, and snippets.

@petsel
Created May 21, 2024 14:47
Show Gist options
  • Save petsel/48c2617ad15c5bb68965a55020142e41 to your computer and use it in GitHub Desktop.
Save petsel/48c2617ad15c5bb68965a55020142e41 to your computer and use it in GitHub Desktop.
// a strictly educational deep clone attempt/approach.
function exposeInternalyType(value) {
return Object.prototype.toString.call(value);
}
function isRegExp(value) {
return exposeInternalyType(value) === '[object RegExp]';
}
function isDate(value) {
return exposeInternalyType(value) === '[object Date]';
}
function deepClone(value) {
let clone = value;
if (value && typeof value === 'object') {
if (isRegExp(value)) {
clone = new RegExp(value);
} else if (isDate(value)) {
clone = new Date(value);
} else if (Array.isArray(value)) {
// recursive cloning.
clone = value.map(deepClone);
} else {
clone = Object.create(Object.getPrototypeOf(value));
const entryList = [
...Object.getOwnPropertyNames(value),
...Object.getOwnPropertySymbols(value),
]
.map(key =>
[key, Reflect.getOwnPropertyDescriptor(value, key)]
);
entryList.forEach(([key, descriptor]) => {
const { writable, enumerable, configurable } = descriptor;
const isPublicValue = Object.hasOwn(descriptor, 'value');
if (writable && enumerable && configurable && isPublicValue) {
// recursive cloning.
// // clone[key] = deepClone(value[key]);
clone[key] = deepClone(descriptor.value);
} else if (isPublicValue) {
// recursive cloning.
// // Reflect.defineProperty(clone, key, { descriptor, value: deepClone(value[key]) });
Reflect.defineProperty(clone, key, { descriptor, value: deepClone(descriptor.value) });
} else {
// assume at least a read-only, `get` protected, value.
// recursive cloning.
Reflect.defineProperty(clone, key, { descriptor, value: deepClone(value[key]) });
// or any other handling of how to clone a protected value.
}
});
}
} else if (typeof value === 'function') {
clone = Function.prototype.bind.call(value);
// or any other handling of how to (not) clone a function.
}
return clone;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment