deep-assign.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. var MAX_MIX_LEVEL = 5; // 最大比对层级
  2. var toString = {}.toString;
  3. // 类型检测
  4. var isType = function (value, type) { return toString.call(value) === '[object ' + type + ']'; };
  5. var isArray = function (value) {
  6. return isType(value, 'Array');
  7. };
  8. var isObjectLike = function (value) {
  9. /**
  10. * isObjectLike({}) => true
  11. * isObjectLike([1, 2, 3]) => true
  12. * isObjectLike(Function) => false
  13. */
  14. return typeof value === 'object' && value !== null;
  15. };
  16. var isPlainObject = function (value) {
  17. /**
  18. * isObjectLike(new Foo) => false
  19. * isObjectLike([1, 2, 3]) => false
  20. * isObjectLike({ x: 0, y: 0 }) => true
  21. */
  22. if (!isObjectLike(value) || !isType(value, 'Object')) {
  23. return false;
  24. }
  25. var proto = value;
  26. while (Object.getPrototypeOf(proto) !== null) {
  27. proto = Object.getPrototypeOf(proto);
  28. }
  29. return Object.getPrototypeOf(value) === proto;
  30. };
  31. /***
  32. * @param {any} dist
  33. * @param {any} src
  34. * @param {number} level 当前层级
  35. * @param {number} maxLevel 最大层级
  36. */
  37. var deep = function (dist, src, level, maxLevel) {
  38. level = level || 0;
  39. maxLevel = maxLevel || MAX_MIX_LEVEL;
  40. for (var key in src) {
  41. if (Object.prototype.hasOwnProperty.call(src, key)) {
  42. var value = src[key];
  43. if (!value) {
  44. // null 、 undefined 等情况直接赋值
  45. dist[key] = value;
  46. }
  47. else {
  48. if (isPlainObject(value)) {
  49. if (!isPlainObject(dist[key])) {
  50. dist[key] = {};
  51. }
  52. if (level < maxLevel) {
  53. deep(dist[key], value, level + 1, maxLevel);
  54. }
  55. else {
  56. // 层级过深直接赋值,性能问题
  57. dist[key] = src[key];
  58. }
  59. }
  60. else if (isArray(value)) {
  61. dist[key] = [];
  62. dist[key] = dist[key].concat(value);
  63. }
  64. else {
  65. dist[key] = value;
  66. }
  67. }
  68. }
  69. }
  70. };
  71. /**
  72. * deepAssign 功能类似 deepMix
  73. * 不同点在于 deepAssign 会将 null undefined 等类型直接覆盖给 source
  74. * 详细参考: __tests__/unit/utils/deep-assign-spec.ts
  75. */
  76. export var deepAssign = function (rst) {
  77. var args = [];
  78. for (var _i = 1; _i < arguments.length; _i++) {
  79. args[_i - 1] = arguments[_i];
  80. }
  81. for (var i = 0; i < args.length; i += 1) {
  82. deep(rst, args[i]);
  83. }
  84. return rst;
  85. };
  86. //# sourceMappingURL=deep-assign.js.map