From bba529a44479828f7c2a9e9c9f4a3bf7f6bb4fe2 Mon Sep 17 00:00:00 2001 From: Mariusz Nowak Date: Fri, 13 Oct 2017 13:19:52 +0200 Subject: [PATCH] feat(copyDeep): duplicate only recursive instances --- object/copy-deep.js | 51 +++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/object/copy-deep.js b/object/copy-deep.js index d1d39c98..bbd20166 100644 --- a/object/copy-deep.js +++ b/object/copy-deep.js @@ -3,40 +3,37 @@ var forEach = require("./for-each") , isPlainObject = require("./is-plain-object") , ensureValue = require("./valid-value") - , isArray = Array.isArray - , copy - , copyItem; + , isArray = Array.isArray; -copyItem = function (value) { - var index; - if (!isPlainObject(value) && !isArray(value)) return value; - index = this[0].indexOf(value); - if (index === -1) return copy.call(this, value); - return this[1][index]; -}; +var copyValue = function (value, ancestors, ancestorsCopy) { + var mode; + if (isPlainObject(value)) mode = "object"; + else if (isArray(value)) mode = "array"; + if (!mode) return value; + + var copy = ancestorsCopy[ancestors.indexOf(value)]; + if (copy) return copy; + copy = mode === "object" ? {} : []; -copy = function (source) { - var target = isArray(source) ? [] : {}; - this[0].push(source); - this[1].push(target); - if (isArray(source)) { - source.forEach(function (value, key) { - target[key] = copyItem.call(this, value, key); - }, this); + ancestors.push(value); + ancestorsCopy.push(copy); + if (mode === "object") { + forEach(value, function (item, key) { + copy[key] = copyValue(item, ancestors, ancestorsCopy); + }); } else { - forEach( - source, - function (value, key) { - target[key] = copyItem.call(this, value, key); - }, - this - ); + value.forEach(function (item, index) { + copy[index] = copyValue(item, ancestors, ancestorsCopy); + }); } - return target; + ancestors.pop(); + ancestorsCopy.pop(); + + return copy; }; module.exports = function (source) { var obj = Object(ensureValue(source)); if (obj !== source) return obj; - return copy.call([[], []], obj); + return copyValue(obj, [], []); };