UNPKG

fclone

Version:

Clone objects by dropping circular references

65 lines (48 loc) 1.45 kB
'use strict'; // see if it looks and smells like an iterable object, and do accept length === 0 function isArrayLike(item) { if (Array.isArray(item)) return true; const len = item && item.length; return typeof len === 'number' && (len === 0 || (len - 1) in item) && typeof item.indexOf === 'function'; } function fclone(obj, refs) { if (!obj || "object" !== typeof obj) return obj; if (obj instanceof Date) { return new Date(obj); } if (typeof Buffer !== 'undefined' && Buffer.isBuffer(obj)) { return new Buffer(obj); } // typed array Int32Array etc. if (typeof obj.subarray === 'function' && /[A-Z][A-Za-z\d]+Array/.test(Object.prototype.toString.call(obj))) { return obj.subarray(0); } if (!refs) { refs = []; } if (isArrayLike(obj)) { refs[refs.length] = obj; let l = obj.length; let i = -1; let copy = []; while (l > ++i) { copy[i] = ~refs.indexOf(obj[i]) ? '[Circular]' : fclone(obj[i], refs); } refs.length && refs.length--; return copy; } refs[refs.length] = obj; let copy = {}; if (obj instanceof Error) { copy.name = obj.name; copy.message = obj.message; copy.stack = obj.stack; } let keys = Object.keys(obj); let l = keys.length; while(l--) { let k = keys[l]; copy[k] = ~refs.indexOf(obj[k]) ? '[Circular]' : fclone(obj[k], refs); } refs.length && refs.length--; return copy; } fclone.default = fclone