assign-deep.js 1.1 KB

12345678910111213141516171819202122232425262728293031323334
  1. "use strict";
  2. var includes = require("../array/#/contains")
  3. , uniq = require("../array/#/uniq")
  4. , copyDeep = require("./copy-deep")
  5. , objForEach = require("./for-each")
  6. , isPlainObject = require("./is-plain-object")
  7. , ensureValue = require("./valid-value");
  8. var isArray = Array.isArray, slice = Array.prototype.slice;
  9. var deepAssign = function (target, source) {
  10. if (target === source) return target;
  11. if (isPlainObject(target) && isPlainObject(source)) {
  12. objForEach(source, function (value, key) { target[key] = deepAssign(target[key], value); });
  13. return target;
  14. }
  15. if (isArray(target) && isArray(source)) {
  16. source.forEach(function (item) {
  17. if (includes.call(target, item)) return;
  18. if (isArray(item) || isPlainObject(item)) item = copyDeep(item);
  19. target.push(item);
  20. });
  21. return target;
  22. }
  23. if (isPlainObject(source) || isArray(source)) return copyDeep(source);
  24. return source;
  25. };
  26. module.exports = function (target/*, ...objects*/) {
  27. return uniq
  28. .call([ensureValue(target)].concat(slice.call(arguments, 1).map(ensureValue)))
  29. .reduce(deepAssign);
  30. };