Skip to content

Instantly share code, notes, and snippets.

@WebReflection
Last active March 27, 2021 19:29
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save WebReflection/031bfab4a19e02e23ba2c2bb75cb2fbe to your computer and use it in GitHub Desktop.
Save WebReflection/031bfab4a19e02e23ba2c2bb75cb2fbe to your computer and use it in GitHub Desktop.
const clone = (() => {
/*! (c) Andrea Giammarchi - WTFPL */
const toString = {}.toString;
const flags = ['global', 'ignoreCase', 'multiline', 'sticky', 'unicode'];
const prime = obj => typeof obj === 'object' ? new obj.constructor(obj.valueOf()) : obj;
const through = obj => {
const descriptors = Object.getOwnPropertyDescriptors(obj);
Reflect.ownKeys(descriptors).forEach(key => {
const descriptor = descriptors[key];
if ('value' in descriptor) {
descriptor.value = clone(descriptor.value);
}
});
return Object.create(
Object.getPrototypeOf(obj),
descriptors
);
};
return obj => {
const asString = toString.call(obj);
switch (asString) {
case '[object Array]': return obj.map(clone);
case '[object Date]': return new Date(obj.toISOString());
case '[object Map]': return new Map(obj.entries());
case '[object Object]': return through(obj);
case '[object Set]': return new Set(obj.values());
case '[object Promise]': return new Promise((res, rej) => obj.then(res, rej));
case '[object RegExp]': return new RegExp(obj.source, flags.map(
flag => obj[flag] ? flag[0] : ''
).join('').replace('s', 'y'));
case '[object Boolean]':
case '[object Number]':
case '[object String]': return prime(obj);
case '[object Null]':
case '[object Undefined]': return obj;
}
switch (true) {
case /Array\]$/.test(asString): return obj.constructor.from(obj);
case /^\[object (?:HTML|SVG)/.test(asString): return obj.cloneNode(true);
case /^\[object Weak/.test(asString):
const w = new obj.constructor;
w.get = key => w.has(key) ? w.get(key) : obj.get(key);
w.has = key => w.has(key) || obj.has(key);
return w;
}
return through(obj);
};
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment