util-helpers 4.11.1 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/index.js CHANGED
@@ -53,6 +53,38 @@ export { default as padZero } from './padZero';
53
53
  * @since 3.1.0
54
54
  * @see 参考 {@link https://github.com/camsong/blog/issues/9|JavaScript 浮点数陷阱及解法}
55
55
  * @see 参考 {@link https://2zbuy.csb.app/|JS浮点数计算测试}
56
+ * @example
57
+ * // 从 4.12.0 版本开始,规范了有效数值参数校验。有效数值即数字或字符串类型,能通过 Number(value) 转为数字,且不为 NaN 、空字符串、空格字符串。
58
+ *
59
+ * // 以下为有效数值:
60
+ * // 1. 数字: 1, -1, 1e-2, 1.312, 0.1, Infinity
61
+ * // 2. 数字字符串: '1', '10e2', '-1', '0.1'
62
+ *
63
+ * // 以下为无效数值:
64
+ * // 1. 非数字的字符串: '', ' ', '1a', '-12a', '10.2.2', '10e2.1'
65
+ * // 2. 其他类型值: undefined, null, true, false, [], {}, new Date(), ...
66
+ *
67
+ * // *注意:Number('') 、 Number(' ') 、 Number(new Date) 、 Number(true)等等是可以返回数字,但都不是有效数值。因为它们分别是空字符串、空格字符串和非数字或字符串类型。
68
+ *
69
+ *
70
+ * // 计算说明:
71
+ * // 1. 全部参数都是无效数值将返回 NaN 。
72
+ * plus(); // NaN
73
+ * plus(new Date()); // NaN
74
+ * plus(true, null); // NaN
75
+ *
76
+ * // 2. 参数中包含有效数值和无效数值,将忽略无效数值。
77
+ * plus(0.1); // 0.1
78
+ * plus('0.1', ' ', true, ); // 0.1
79
+ * plus(true, 0.1); // 0.1
80
+ * plus(true, 0.1, 0.2); // 0.3
81
+ * plus('', 0.1, ' ', new Date(), 0.2); // 0.3
82
+ * plus(0.1, true, 0.2, null); // 0.3
83
+ *
84
+ * // 3. 数字和数字字符串将正常的使用安全计算
85
+ * plus(0.1, 0.2); // 0.3
86
+ * plus(0.1, 0.2, 0.3); // 0.6
87
+ *
56
88
  */
57
89
 
58
90
  export { default as plus } from './plus';
package/esm/minus.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import { digitLength } from './utils/math.util';
2
+ import { digitLength, isEffectiveNumeric } from './utils/math.util';
3
3
  import times from './times';
4
- import { isNumber, isNaN, isString } from './utils/type';
5
4
  /**
6
5
  * 精确减法,支持多个数相减
7
6
  *
@@ -33,12 +32,13 @@ function minus() {
33
32
 
34
33
  if (rest.length > 0) {
35
34
  return minus.apply(void 0, [minus(num1, num2)].concat(_toConsumableArray(rest)));
36
- } // 兼容处理,如果第2个参数为非数字或字符串时,返回第一个参数
35
+ } // 兼容处理,如果参数包含无效数值时,尝试取出有效数值参数
37
36
 
38
37
 
39
- if ((!isNumber(num2) || isNaN(num2)) && !isString(num2)) {
40
- // @ts-ignore
41
- return num1;
38
+ if (!isEffectiveNumeric(num1)) {
39
+ return isEffectiveNumeric(num2) ? Number(num2) : NaN;
40
+ } else if (!isEffectiveNumeric(num2)) {
41
+ return Number(num1);
42
42
  }
43
43
 
44
44
  var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
package/esm/plus.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import { digitLength } from './utils/math.util';
2
+ import { digitLength, isEffectiveNumeric } from './utils/math.util';
3
3
  import times from './times';
4
- import { isNumber, isNaN, isString } from './utils/type';
5
4
  /**
6
5
  * 精确加法,支持多个数相加
7
6
  *
@@ -33,12 +32,13 @@ function plus() {
33
32
 
34
33
  if (rest.length > 0) {
35
34
  return plus.apply(void 0, [plus(num1, num2)].concat(_toConsumableArray(rest)));
36
- } // 兼容处理,如果第2个参数为非数字或字符串时,返回第一个参数
35
+ } // 兼容处理,如果参数包含无效数值时,尝试取出有效数值参数
37
36
 
38
37
 
39
- if ((!isNumber(num2) || isNaN(num2)) && !isString(num2)) {
40
- // @ts-ignore
41
- return num1;
38
+ if (!isEffectiveNumeric(num1)) {
39
+ return isEffectiveNumeric(num2) ? Number(num2) : NaN;
40
+ } else if (!isEffectiveNumeric(num2)) {
41
+ return Number(num1);
42
42
  }
43
43
 
44
44
  var baseNum = Math.pow(10, Math.max(digitLength(num1), digitLength(num2)));
package/esm/round.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import divide from './divide';
2
2
  import times from './times';
3
- import { isNumber, isString, isNaN } from './utils/type';
3
+ import { isEffectiveNumeric } from './utils/math.util';
4
4
  /**
5
5
  * 四舍五入,支持设置精度
6
6
  *
@@ -25,10 +25,9 @@ import { isNumber, isString, isNaN } from './utils/type';
25
25
  function round(num) {
26
26
  var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
27
27
 
28
- // 兼容处理,如果参数为非数字或字符串时,直接返回
29
- if ((!isNumber(num) || isNaN(num)) && !isString(num)) {
30
- // @ts-ignore
31
- return num;
28
+ // 兼容处理,如果参数包含无效数值时,返回第一个参数
29
+ if (!isEffectiveNumeric(num)) {
30
+ return NaN;
32
31
  }
33
32
 
34
33
  var base = Math.pow(10, precision);
package/esm/times.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
- import { digitLength, float2Fixed, checkBoundary } from './utils/math.util';
3
- import { isNumber, isNaN, isString } from './utils/type';
2
+ import { digitLength, float2Fixed, checkBoundary, isEffectiveNumeric } from './utils/math.util';
4
3
  /**
5
4
  * 精确乘法,支持多个数相乘
6
5
  *
@@ -32,12 +31,13 @@ function times() {
32
31
 
33
32
  if (rest.length > 0) {
34
33
  return times.apply(void 0, [times(num1, num2)].concat(_toConsumableArray(rest)));
35
- } // 兼容处理,如果第2个参数为非数字或字符串时,返回第一个参数
34
+ } // 兼容处理,如果参数包含无效数值时,尝试取出有效数值参数
36
35
 
37
36
 
38
- if ((!isNumber(num2) || isNaN(num2)) && !isString(num2)) {
39
- // @ts-ignore
40
- return num1;
37
+ if (!isEffectiveNumeric(num1)) {
38
+ return isEffectiveNumeric(num2) ? Number(num2) : NaN;
39
+ } else if (!isEffectiveNumeric(num2)) {
40
+ return Number(num1);
41
41
  }
42
42
 
43
43
  var num1Changed = float2Fixed(num1);
@@ -6,6 +6,36 @@
6
6
  */
7
7
  import { MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from './constants';
8
8
  import devWarn from './devWarn';
9
+ import { isNumber, isString } from './type';
10
+ /**
11
+ * 值是否为有效的数值
12
+ *
13
+ * @param {*} value 待检测的值
14
+ * @returns {boolean} 是否为有效的数值
15
+ */
16
+
17
+ export function isEffectiveNumeric(value) {
18
+ if (isNumber(value) && !isNaN(value)) {
19
+ return true;
20
+ } // 避免空字符串 或 带空格的字符串
21
+
22
+
23
+ if (isString(value)) {
24
+ var fmtStrValue = value.trim(); // 带空格的字符串也不转换数字
25
+ // Number(' ') => 0
26
+
27
+ if (fmtStrValue === value) {
28
+ var numValue = fmtStrValue ? Number(fmtStrValue) : NaN;
29
+
30
+ if (isNumber(numValue) && !isNaN(numValue)) {
31
+ return true;
32
+ }
33
+ }
34
+ }
35
+
36
+ devWarn("".concat(value, " is not a valid number."));
37
+ return false;
38
+ }
9
39
  /**
10
40
  * 是否为科学计数法数字
11
41
  *
package/lib/divide.js CHANGED
@@ -9,8 +9,6 @@ var _math = require("./utils/math.util");
9
9
 
10
10
  var _times = _interopRequireDefault(require("./times"));
11
11
 
12
- var _type = require("./utils/type");
13
-
14
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
13
 
16
14
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
@@ -55,12 +53,13 @@ function divide() {
55
53
 
56
54
  if (rest.length > 0) {
57
55
  return divide.apply(void 0, [divide(num1, num2)].concat(_toConsumableArray(rest)));
58
- } // 兼容处理,如果第2个参数为非数字或字符串时,返回第一个参数
56
+ } // 兼容处理,如果参数包含无效数值时,尝试取出有效数值参数
59
57
 
60
58
 
61
- if ((!(0, _type.isNumber)(num2) || (0, _type.isNaN)(num2)) && !(0, _type.isString)(num2)) {
62
- // @ts-ignore
63
- return num1;
59
+ if (!(0, _math.isEffectiveNumeric)(num1)) {
60
+ return (0, _math.isEffectiveNumeric)(num2) ? Number(num2) : NaN;
61
+ } else if (!(0, _math.isEffectiveNumeric)(num2)) {
62
+ return Number(num1);
64
63
  }
65
64
 
66
65
  var num1Changed = (0, _math.float2Fixed)(num1);
package/lib/minus.js CHANGED
@@ -9,8 +9,6 @@ var _math = require("./utils/math.util");
9
9
 
10
10
  var _times = _interopRequireDefault(require("./times"));
11
11
 
12
- var _type = require("./utils/type");
13
-
14
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
13
 
16
14
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
@@ -55,12 +53,13 @@ function minus() {
55
53
 
56
54
  if (rest.length > 0) {
57
55
  return minus.apply(void 0, [minus(num1, num2)].concat(_toConsumableArray(rest)));
58
- } // 兼容处理,如果第2个参数为非数字或字符串时,返回第一个参数
56
+ } // 兼容处理,如果参数包含无效数值时,尝试取出有效数值参数
59
57
 
60
58
 
61
- if ((!(0, _type.isNumber)(num2) || (0, _type.isNaN)(num2)) && !(0, _type.isString)(num2)) {
62
- // @ts-ignore
63
- return num1;
59
+ if (!(0, _math.isEffectiveNumeric)(num1)) {
60
+ return (0, _math.isEffectiveNumeric)(num2) ? Number(num2) : NaN;
61
+ } else if (!(0, _math.isEffectiveNumeric)(num2)) {
62
+ return Number(num1);
64
63
  }
65
64
 
66
65
  var baseNum = Math.pow(10, Math.max((0, _math.digitLength)(num1), (0, _math.digitLength)(num2)));
package/lib/plus.js CHANGED
@@ -9,8 +9,6 @@ var _math = require("./utils/math.util");
9
9
 
10
10
  var _times = _interopRequireDefault(require("./times"));
11
11
 
12
- var _type = require("./utils/type");
13
-
14
12
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
13
 
16
14
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
@@ -55,12 +53,13 @@ function plus() {
55
53
 
56
54
  if (rest.length > 0) {
57
55
  return plus.apply(void 0, [plus(num1, num2)].concat(_toConsumableArray(rest)));
58
- } // 兼容处理,如果第2个参数为非数字或字符串时,返回第一个参数
56
+ } // 兼容处理,如果参数包含无效数值时,尝试取出有效数值参数
59
57
 
60
58
 
61
- if ((!(0, _type.isNumber)(num2) || (0, _type.isNaN)(num2)) && !(0, _type.isString)(num2)) {
62
- // @ts-ignore
63
- return num1;
59
+ if (!(0, _math.isEffectiveNumeric)(num1)) {
60
+ return (0, _math.isEffectiveNumeric)(num2) ? Number(num2) : NaN;
61
+ } else if (!(0, _math.isEffectiveNumeric)(num2)) {
62
+ return Number(num1);
64
63
  }
65
64
 
66
65
  var baseNum = Math.pow(10, Math.max((0, _math.digitLength)(num1), (0, _math.digitLength)(num2)));
package/lib/round.js CHANGED
@@ -9,7 +9,7 @@ var _divide = _interopRequireDefault(require("./divide"));
9
9
 
10
10
  var _times = _interopRequireDefault(require("./times"));
11
11
 
12
- var _type = require("./utils/type");
12
+ var _math = require("./utils/math.util");
13
13
 
14
14
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
15
15
 
@@ -36,10 +36,9 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "d
36
36
  function round(num) {
37
37
  var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
38
38
 
39
- // 兼容处理,如果参数为非数字或字符串时,直接返回
40
- if ((!(0, _type.isNumber)(num) || (0, _type.isNaN)(num)) && !(0, _type.isString)(num)) {
41
- // @ts-ignore
42
- return num;
39
+ // 兼容处理,如果参数包含无效数值时,返回第一个参数
40
+ if (!(0, _math.isEffectiveNumeric)(num)) {
41
+ return NaN;
43
42
  }
44
43
 
45
44
  var base = Math.pow(10, precision);
package/lib/times.js CHANGED
@@ -7,8 +7,6 @@ exports["default"] = void 0;
7
7
 
8
8
  var _math = require("./utils/math.util");
9
9
 
10
- var _type = require("./utils/type");
11
-
12
10
  function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
13
11
 
14
12
  function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
@@ -51,12 +49,13 @@ function times() {
51
49
 
52
50
  if (rest.length > 0) {
53
51
  return times.apply(void 0, [times(num1, num2)].concat(_toConsumableArray(rest)));
54
- } // 兼容处理,如果第2个参数为非数字或字符串时,返回第一个参数
52
+ } // 兼容处理,如果参数包含无效数值时,尝试取出有效数值参数
55
53
 
56
54
 
57
- if ((!(0, _type.isNumber)(num2) || (0, _type.isNaN)(num2)) && !(0, _type.isString)(num2)) {
58
- // @ts-ignore
59
- return num1;
55
+ if (!(0, _math.isEffectiveNumeric)(num1)) {
56
+ return (0, _math.isEffectiveNumeric)(num2) ? Number(num2) : NaN;
57
+ } else if (!(0, _math.isEffectiveNumeric)(num2)) {
58
+ return Number(num1);
60
59
  }
61
60
 
62
61
  var num1Changed = (0, _math.float2Fixed)(num1);
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.isEffectiveNumeric = isEffectiveNumeric;
6
7
  exports.isScientificNumber = isScientificNumber;
7
8
  exports.strip = strip;
8
9
  exports.digitLength = digitLength;
@@ -15,6 +16,8 @@ var _constants = require("./constants");
15
16
 
16
17
  var _devWarn = _interopRequireDefault(require("./devWarn"));
17
18
 
19
+ var _type = require("./type");
20
+
18
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
19
22
 
20
23
  /**
@@ -24,12 +27,42 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "d
24
27
  * 问题示例:2.3 + 2.4 = 4.699999999999999,1.0 - 0.9 = 0.09999999999999998
25
28
  */
26
29
 
30
+ /**
31
+ * 值是否为有效的数值
32
+ *
33
+ * @param {*} value 待检测的值
34
+ * @returns {boolean} 是否为有效的数值
35
+ */
36
+ function isEffectiveNumeric(value) {
37
+ if ((0, _type.isNumber)(value) && !isNaN(value)) {
38
+ return true;
39
+ } // 避免空字符串 或 带空格的字符串
40
+
41
+
42
+ if ((0, _type.isString)(value)) {
43
+ var fmtStrValue = value.trim(); // 带空格的字符串也不转换数字
44
+ // Number(' ') => 0
45
+
46
+ if (fmtStrValue === value) {
47
+ var numValue = fmtStrValue ? Number(fmtStrValue) : NaN;
48
+
49
+ if ((0, _type.isNumber)(numValue) && !isNaN(numValue)) {
50
+ return true;
51
+ }
52
+ }
53
+ }
54
+
55
+ (0, _devWarn["default"])("".concat(value, " is not a valid number."));
56
+ return false;
57
+ }
27
58
  /**
28
59
  * 是否为科学计数法数字
29
60
  *
30
61
  * @param {string} num 检查值
31
62
  * @returns {boolean}
32
63
  */
64
+
65
+
33
66
  function isScientificNumber(num) {
34
67
  return /\d+\.?\d*e[\+\-]*\d+/i.test(num);
35
68
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "util-helpers",
3
- "version": "4.11.1",
3
+ "version": "4.12.0",
4
4
  "description": "一个基于业务场景的工具方法库",
5
5
  "main": "lib/index.js",
6
6
  "module": "esm/index.js",
@@ -1,3 +1,10 @@
1
+ /**
2
+ * 值是否为有效的数值
3
+ *
4
+ * @param {*} value 待检测的值
5
+ * @returns {boolean} 是否为有效的数值
6
+ */
7
+ export function isEffectiveNumeric(value: any): boolean;
1
8
  /**
2
9
  * 是否为科学计数法数字
3
10
  *