You can store links and results in separate arrays, and when you find a property with the same link, you just need to return the result in caching.
function deepClone(o) { var references = []; var cachedResults = []; function clone(obj) { if (typeof obj !== 'object') return obj; var index = references.indexOf(obj); if (index !== -1) return cachedResults[index]; references.push(obj); var result = Array.isArray(obj) ? [] : obj.constructor ? new obj.constructor() : {}; cachedResults.push(result); for (var key in obj) if (obj.hasOwnProperty(key)) result[key] = clone(obj[key]); return result; } return clone(o); }
I deleted the map and some other type comparisons to make it more readable.
Check ES6's robust response to @trincot if you can target modern browsers.
source share