merge.js 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. var clone = require('./clone');
  2. module.exports = merge;
  3. function typesMatch(a, b) {
  4. return (typeof a === typeof b) && (Array.isArray(a) === Array.isArray(b));
  5. }
  6. /**
  7. * A deep merge of the source based on the target.
  8. * @param {Object} source [description]
  9. * @param {Object} target [description]
  10. * @return {Object} [description]
  11. */
  12. function merge(source, target, result) {
  13. if (result === undefined) {
  14. result = clone(source);
  15. }
  16. // merge missing values from the target to the source
  17. Object.getOwnPropertyNames(target).forEach(function (key) {
  18. if (source[key] === undefined) {
  19. result[key] = target[key];
  20. }
  21. });
  22. Object.getOwnPropertyNames(source).forEach(function (key) {
  23. var value = source[key];
  24. if (target[key] && typesMatch(value, target[key])) {
  25. // merge empty values
  26. if (value === '') {
  27. result[key] = target[key];
  28. }
  29. if (Array.isArray(value)) {
  30. if (value.length === 0 && target[key].length) {
  31. result[key] = target[key].slice(0);
  32. }
  33. } else if (typeof value === 'object') {
  34. result[key] = merge(value, target[key]);
  35. }
  36. }
  37. });
  38. return result;
  39. }