extend.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. export default function extend() {
  2. let options,
  3. name,
  4. src,
  5. copy,
  6. copyIsArray,
  7. clone,
  8. target = arguments[0] || {},
  9. i = 1,
  10. length = arguments.length,
  11. deep = false;
  12. // Handle a deep copy situation
  13. if (typeof target === "boolean") {
  14. deep = target;
  15. // Skip the boolean and the target
  16. target = arguments[i] || {};
  17. i++;
  18. }
  19. // Handle case when target is a string or something (possible in deep copy)
  20. if (typeof target !== "object" && typeof target !== "function") {
  21. target = {};
  22. }
  23. for (; i < length; i++) {
  24. // Only deal with non-null/undefined values
  25. if ((options = arguments[i]) != null) {
  26. // Extend the base object
  27. for (name in options) {
  28. src = target[name];
  29. copy = options[name];
  30. // Prevent never-ending loop
  31. if (target === copy) {
  32. continue;
  33. }
  34. // Recurse if we're merging plain objects or arrays
  35. if (
  36. deep &&
  37. copy &&
  38. (Object.prototype.toString.call(copy) === "[object Object]" ||
  39. (copyIsArray = Array.isArray(copy)))
  40. ) {
  41. if (copyIsArray) {
  42. copyIsArray = false;
  43. clone = src && Array.isArray(src) ? src : [];
  44. } else {
  45. clone =
  46. src && Object.prototype.toString.call(src) === "[object Object]"
  47. ? src
  48. : {};
  49. }
  50. // Never move original objects, clone them
  51. target[name] = extend(deep, clone, copy);
  52. // Don't bring in undefined values
  53. } else if (copy !== undefined) {
  54. target[name] = copy;
  55. }
  56. }
  57. }
  58. }
  59. // Return the modified object
  60. return target;
  61. }