a-js-tools 1.0.3 → 1.0.5

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/index.cjs CHANGED
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
 
3
+ var createConstructor = require('./src/object/createConstructor.cjs');
3
4
  var getRandomNumber = require('./src/getRandomNumber.cjs');
4
5
  var className = require('./src/className.cjs');
5
6
  var getRandomString = require('./src/getRandomString.cjs');
@@ -16,6 +17,7 @@ var symmetricDifference = require('./src/array/symmetricDifference.cjs');
16
17
 
17
18
 
18
19
 
20
+ exports.createConstructor = createConstructor.createConstructor;
19
21
  exports.getRandomFloat = getRandomNumber.getRandomFloat;
20
22
  exports.getRandomInt = getRandomNumber.getRandomInt;
21
23
  exports.toLowerCamelCase = className.toLowerCamelCase;
package/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
+ import { CreateConstructor, createConstructor } from 'src/object/createConstructor';
1
2
  export { toLowerCamelCase, toSplitCase, getRandomFloat, getRandomInt, getRandomString, } from './src/index';
2
3
  export { throttle, debounce } from './src/performance';
3
4
  export type { DebounceAndThrottleReturnType } from './src/performance';
4
5
  export { escapeRegExp, autoEscapedRegExp } from './src/regexp';
5
6
  export { isBrowser, isNode } from './src/isNode';
6
7
  export { intersection, enArr, union, difference, symmetricDifference, } from './src/array/';
8
+ export { createConstructor };
9
+ export type { CreateConstructor };
7
10
  export { sleep } from './src/sleep';
package/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ export { createConstructor } from './src/object/createConstructor.mjs';
1
2
  export { getRandomFloat, getRandomInt } from './src/getRandomNumber.mjs';
2
3
  export { toLowerCamelCase, toSplitCase } from './src/className.mjs';
3
4
  export { getRandomString } from './src/getRandomString.mjs';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "type": "module",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "name": "a-js-tools",
5
5
  "description": "一点点 🤏 js 函数",
6
6
  "license": "MIT",
@@ -34,12 +34,10 @@ var aTypeOfJs = require('a-type-of-js');
34
34
  *
35
35
  */
36
36
  function difference(a, b) {
37
- if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b)) {
37
+ if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b))
38
38
  throw new TypeError('参数需为数组');
39
- }
40
- if (a.length === 0 || b.length === 0) {
39
+ if (aTypeOfJs.isEmptyArray(a) || aTypeOfJs.isEmptyArray(b))
41
40
  return a;
42
- }
43
41
  /** 获取两个数组中长度较小的 */
44
42
  // 参数有顺序要求
45
43
  // const [shorter, longer] = a.length > b.length ? [b, a] : [a, b];
@@ -1,4 +1,4 @@
1
- import { isArray } from 'a-type-of-js';
1
+ import { isArray, isEmptyArray } from 'a-type-of-js';
2
2
 
3
3
  /**
4
4
  * 求给出的两个数组的差值(A - B)
@@ -32,12 +32,10 @@ import { isArray } from 'a-type-of-js';
32
32
  *
33
33
  */
34
34
  function difference(a, b) {
35
- if (!isArray(a) || !isArray(b)) {
35
+ if (!isArray(a) || !isArray(b))
36
36
  throw new TypeError('参数需为数组');
37
- }
38
- if (a.length === 0 || b.length === 0) {
37
+ if (isEmptyArray(a) || isEmptyArray(b))
39
38
  return a;
40
- }
41
39
  /** 获取两个数组中长度较小的 */
42
40
  // 参数有顺序要求
43
41
  // const [shorter, longer] = a.length > b.length ? [b, a] : [a, b];
@@ -24,13 +24,11 @@ var aTypeOfJs = require('a-type-of-js');
24
24
  *
25
25
  */
26
26
  function intersection(a, b) {
27
- if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b)) {
27
+ if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b))
28
28
  throw new TypeError('参数必须是数组类型数据');
29
- }
30
29
  // 任意数组为空,则返回空数组
31
- if (a.length === 0 || b.length === 0) {
30
+ if (aTypeOfJs.isEmptyArray(a) || aTypeOfJs.isEmptyArray(b))
32
31
  return [];
33
- }
34
32
  /**
35
33
  * 在实际运算中, new Set() 的 开销为 O(n) ,filter 的开销也为 O(n)
36
34
  *
@@ -1,4 +1,4 @@
1
- import { isArray } from 'a-type-of-js';
1
+ import { isArray, isEmptyArray } from 'a-type-of-js';
2
2
 
3
3
  /**
4
4
  *
@@ -22,13 +22,11 @@ import { isArray } from 'a-type-of-js';
22
22
  *
23
23
  */
24
24
  function intersection(a, b) {
25
- if (!isArray(a) || !isArray(b)) {
25
+ if (!isArray(a) || !isArray(b))
26
26
  throw new TypeError('参数必须是数组类型数据');
27
- }
28
27
  // 任意数组为空,则返回空数组
29
- if (a.length === 0 || b.length === 0) {
28
+ if (isEmptyArray(a) || isEmptyArray(b))
30
29
  return [];
31
- }
32
30
  /**
33
31
  * 在实际运算中, new Set() 的 开销为 O(n) ,filter 的开销也为 O(n)
34
32
  *
@@ -36,15 +36,12 @@ var difference = require('./difference.cjs');
36
36
  *
37
37
  */
38
38
  function symmetricDifference(a, b) {
39
- if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b)) {
39
+ if (!aTypeOfJs.isArray(a) || !aTypeOfJs.isArray(b))
40
40
  throw new TypeError('参数必须是数组');
41
- }
42
- if (a.length === 0) {
41
+ if (aTypeOfJs.isEmptyArray(a))
43
42
  return [...b];
44
- }
45
- if (b.length === 0) {
43
+ if (aTypeOfJs.isEmptyArray(b))
46
44
  return [...a];
47
- }
48
45
  return [...difference.difference(a, b), ...difference.difference(b, a)];
49
46
  }
50
47
 
@@ -1,4 +1,4 @@
1
- import { isArray } from 'a-type-of-js';
1
+ import { isArray, isEmptyArray } from 'a-type-of-js';
2
2
  import { difference } from './difference.mjs';
3
3
 
4
4
  /**
@@ -34,15 +34,12 @@ import { difference } from './difference.mjs';
34
34
  *
35
35
  */
36
36
  function symmetricDifference(a, b) {
37
- if (!isArray(a) || !isArray(b)) {
37
+ if (!isArray(a) || !isArray(b))
38
38
  throw new TypeError('参数必须是数组');
39
- }
40
- if (a.length === 0) {
39
+ if (isEmptyArray(a))
41
40
  return [...b];
42
- }
43
- if (b.length === 0) {
41
+ if (isEmptyArray(b))
44
42
  return [...a];
45
- }
46
43
  return [...difference(a, b), ...difference(b, a)];
47
44
  }
48
45
 
@@ -44,20 +44,16 @@ var aTypeOfJs = require('a-type-of-js');
44
44
  *
45
45
  */
46
46
  function union(...arrays) {
47
- if (arrays.length === 0) {
47
+ if (aTypeOfJs.isEmptyArray(arrays))
48
48
  return [];
49
- }
50
- if (arrays.some(i => !aTypeOfJs.isArray(i))) {
49
+ if (arrays.some(i => !aTypeOfJs.isArray(i)))
51
50
  throw new TypeError('参数必须都是数组形式的元素');
52
- }
53
- if (arrays.length === 1) {
51
+ if (arrays.length === 1)
54
52
  return [...arrays[0]];
55
- }
56
53
  const resultSet = new Set();
57
54
  for (const array of arrays) {
58
- for (const item of array) {
55
+ for (const item of array)
59
56
  resultSet.add(item);
60
- }
61
57
  }
62
58
  return Array.from(resultSet);
63
59
  }
@@ -1,4 +1,4 @@
1
- import { isArray } from 'a-type-of-js';
1
+ import { isEmptyArray, isArray } from 'a-type-of-js';
2
2
 
3
3
  /**
4
4
  *
@@ -42,20 +42,16 @@ import { isArray } from 'a-type-of-js';
42
42
  *
43
43
  */
44
44
  function union(...arrays) {
45
- if (arrays.length === 0) {
45
+ if (isEmptyArray(arrays))
46
46
  return [];
47
- }
48
- if (arrays.some(i => !isArray(i))) {
47
+ if (arrays.some(i => !isArray(i)))
49
48
  throw new TypeError('参数必须都是数组形式的元素');
50
- }
51
- if (arrays.length === 1) {
49
+ if (arrays.length === 1)
52
50
  return [...arrays[0]];
53
- }
54
51
  const resultSet = new Set();
55
52
  for (const array of arrays) {
56
- for (const item of array) {
53
+ for (const item of array)
57
54
  resultSet.add(item);
58
- }
59
55
  }
60
56
  return Array.from(resultSet);
61
57
  }
package/src/className.cjs CHANGED
@@ -34,9 +34,9 @@ initial = false) {
34
34
  /** 转化首字符 */
35
35
  const toTransform = (_str, _dividingType) => _str.replace(new RegExp(`${template.test(_dividingType) ? `\\${_dividingType}` : _dividingType}([a-zA-Z])`, 'g'), (match, p1) => p1.toUpperCase());
36
36
  // 多分隔符转化
37
- dividingType.split('').forEach((item) => {
38
- result = toTransform(result, item);
39
- });
37
+ dividingType
38
+ .split('')
39
+ .forEach((item) => (result = toTransform(result, item)));
40
40
  return initial
41
41
  ? result.replace(/^./, (match) => match.toUpperCase())
42
42
  : result;
package/src/className.mjs CHANGED
@@ -32,9 +32,9 @@ initial = false) {
32
32
  /** 转化首字符 */
33
33
  const toTransform = (_str, _dividingType) => _str.replace(new RegExp(`${template.test(_dividingType) ? `\\${_dividingType}` : _dividingType}([a-zA-Z])`, 'g'), (match, p1) => p1.toUpperCase());
34
34
  // 多分隔符转化
35
- dividingType.split('').forEach((item) => {
36
- result = toTransform(result, item);
37
- });
35
+ dividingType
36
+ .split('')
37
+ .forEach((item) => (result = toTransform(result, item)));
38
38
  return initial
39
39
  ? result.replace(/^./, (match) => match.toUpperCase())
40
40
  : result;
@@ -38,9 +38,8 @@ function getRandomString(options) {
38
38
  (aTypeOfJs.isPlainObject(options) &&
39
39
  (!aTypeOfJs.isNumber(options.length) ||
40
40
  options.length < 1 ||
41
- !Number.isInteger(options.length)))) {
41
+ !Number.isInteger(options.length))))
42
42
  throw new TypeError('参数类型错误 ❌ (getRandomString)');
43
- }
44
43
  const initOptions = {
45
44
  length: 32,
46
45
  chars: 'abcdefghijklmnopqrstuvwxyz',
@@ -52,13 +51,11 @@ function getRandomString(options) {
52
51
  includeSpecial: false,
53
52
  };
54
53
  /// 生成 UUID
55
- if (initOptions.type === 'uuid') {
54
+ if (initOptions.type === 'uuid')
56
55
  return crypto.randomUUID();
57
- }
58
- if (aTypeOfJs.isNumber(options) && Number.isInteger(options) && options > 0) {
59
- // 验证输入参数
56
+ // 验证输入参数
57
+ if (aTypeOfJs.isNumber(options) && Number.isInteger(options) && options > 0)
60
58
  Object.assign(initOptions, { length: options });
61
- }
62
59
  if (aTypeOfJs.isPlainObject(options)) {
63
60
  Object.assign(initOptions, options);
64
61
  initOptions.length = initOptions.length < 1 ? 32 : initOptions.length;
@@ -66,17 +63,14 @@ function getRandomString(options) {
66
63
  /** 生成随机字符串 */
67
64
  const templateCharsArr = initOptions.chars.split('');
68
65
  // 添加大写字母
69
- if (initOptions.includeUppercaseLetters) {
66
+ if (initOptions.includeUppercaseLetters)
70
67
  interleaveString(templateCharsArr, initOptions.chars.toUpperCase());
71
- }
72
68
  // 添加数字
73
- if (initOptions.includeNumbers) {
69
+ if (initOptions.includeNumbers)
74
70
  interleaveString(templateCharsArr, initOptions.chars2);
75
- }
76
71
  // 添加特殊字符
77
- if (initOptions.includeSpecial) {
72
+ if (initOptions.includeSpecial)
78
73
  interleaveString(templateCharsArr, initOptions.chars3);
79
- }
80
74
  // 使用密码学安全的随机数生成器
81
75
  const bytes = isNode.isBrowser() && window.crypto
82
76
  ? window.crypto.getRandomValues(new Uint8Array(initOptions.length))
@@ -104,12 +98,10 @@ function getRandomString(options) {
104
98
  const str1Length = str1.length, str2Length = str2.length;
105
99
  const maxLength = Math.max(str1Length, str2Length);
106
100
  for (let i = 0; i < maxLength; i++) {
107
- if (i < str1Length && str2[i] !== undefined) {
101
+ if (i < str1Length && !aTypeOfJs.isUndefined(str2[i]))
108
102
  str1[i] += str2[i];
109
- }
110
- else if (i < str2Length) {
103
+ else if (i < str2Length)
111
104
  str1[i] = str2[i];
112
- }
113
105
  }
114
106
  }
115
107
  return result;
@@ -1,4 +1,4 @@
1
- import { isPlainObject, isNumber, isNaN } from 'a-type-of-js';
1
+ import { isPlainObject, isNumber, isNaN, isUndefined } from 'a-type-of-js';
2
2
  import { isBrowser } from './isNode.mjs';
3
3
 
4
4
  /**
@@ -36,9 +36,8 @@ function getRandomString(options) {
36
36
  (isPlainObject(options) &&
37
37
  (!isNumber(options.length) ||
38
38
  options.length < 1 ||
39
- !Number.isInteger(options.length)))) {
39
+ !Number.isInteger(options.length))))
40
40
  throw new TypeError('参数类型错误 ❌ (getRandomString)');
41
- }
42
41
  const initOptions = {
43
42
  length: 32,
44
43
  chars: 'abcdefghijklmnopqrstuvwxyz',
@@ -50,13 +49,11 @@ function getRandomString(options) {
50
49
  includeSpecial: false,
51
50
  };
52
51
  /// 生成 UUID
53
- if (initOptions.type === 'uuid') {
52
+ if (initOptions.type === 'uuid')
54
53
  return crypto.randomUUID();
55
- }
56
- if (isNumber(options) && Number.isInteger(options) && options > 0) {
57
- // 验证输入参数
54
+ // 验证输入参数
55
+ if (isNumber(options) && Number.isInteger(options) && options > 0)
58
56
  Object.assign(initOptions, { length: options });
59
- }
60
57
  if (isPlainObject(options)) {
61
58
  Object.assign(initOptions, options);
62
59
  initOptions.length = initOptions.length < 1 ? 32 : initOptions.length;
@@ -64,17 +61,14 @@ function getRandomString(options) {
64
61
  /** 生成随机字符串 */
65
62
  const templateCharsArr = initOptions.chars.split('');
66
63
  // 添加大写字母
67
- if (initOptions.includeUppercaseLetters) {
64
+ if (initOptions.includeUppercaseLetters)
68
65
  interleaveString(templateCharsArr, initOptions.chars.toUpperCase());
69
- }
70
66
  // 添加数字
71
- if (initOptions.includeNumbers) {
67
+ if (initOptions.includeNumbers)
72
68
  interleaveString(templateCharsArr, initOptions.chars2);
73
- }
74
69
  // 添加特殊字符
75
- if (initOptions.includeSpecial) {
70
+ if (initOptions.includeSpecial)
76
71
  interleaveString(templateCharsArr, initOptions.chars3);
77
- }
78
72
  // 使用密码学安全的随机数生成器
79
73
  const bytes = isBrowser() && window.crypto
80
74
  ? window.crypto.getRandomValues(new Uint8Array(initOptions.length))
@@ -102,12 +96,10 @@ function getRandomString(options) {
102
96
  const str1Length = str1.length, str2Length = str2.length;
103
97
  const maxLength = Math.max(str1Length, str2Length);
104
98
  for (let i = 0; i < maxLength; i++) {
105
- if (i < str1Length && str2[i] !== undefined) {
99
+ if (i < str1Length && !isUndefined(str2[i]))
106
100
  str1[i] += str2[i];
107
- }
108
- else if (i < str2Length) {
101
+ else if (i < str2Length)
109
102
  str1[i] = str2[i];
110
- }
111
103
  }
112
104
  }
113
105
  return result;
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ *
5
+ * 构建一个 Constructor 构造函数
6
+ *
7
+ * 接收一个构造函数,然后返回 TS 能识别的构造函数自身
8
+ *
9
+ * 函数本身并没有执行任何逻辑,仅是简单的返回了实参自身
10
+ *
11
+ * 而经过该函数的包装,构造函数成了能够被 TS 识别为可用 new 实例的构造函数
12
+ *
13
+ * @param constructor - 传入一个构造函数
14
+ * @returns 返回传入的构造函数
15
+ *
16
+ * ```ts
17
+ * import { createConstructor } from "a-js-tools";
18
+ *
19
+ * type Tom = {
20
+ * a: number
21
+ * }
22
+ *
23
+ * function _Tom (this: TomType): Tom {
24
+ * this.a = 1;
25
+ *
26
+ * return this;
27
+ * }
28
+ *
29
+ * // 逻辑上没有错,但是会造成 ts 显示
30
+ * // 其目标缺少构造签名的 "new" 表达式隐式具有 "any" 类型。ts(7009)
31
+ * const a = new _Tom();
32
+ *
33
+ * const tomConstructor = createConstructor(_tom);
34
+ *
35
+ * const b = new tomConstructor(); // 这时就不会显示错误
36
+ *
37
+ * ```
38
+ *
39
+ */
40
+ function createConstructor(constructor) {
41
+ return constructor;
42
+ }
43
+
44
+ exports.createConstructor = createConstructor;
@@ -0,0 +1,47 @@
1
+ /**
2
+ *
3
+ * 构建构建的构建函数
4
+ *
5
+ *
6
+ */
7
+ export interface CreateConstructor<T, Args extends unknown[] = unknown[]> {
8
+ new (...args: Args): T;
9
+ }
10
+ /**
11
+ *
12
+ * 构建一个 Constructor 构造函数
13
+ *
14
+ * 接收一个构造函数,然后返回 TS 能识别的构造函数自身
15
+ *
16
+ * 函数本身并没有执行任何逻辑,仅是简单的返回了实参自身
17
+ *
18
+ * 而经过该函数的包装,构造函数成了能够被 TS 识别为可用 new 实例的构造函数
19
+ *
20
+ * @param constructor - 传入一个构造函数
21
+ * @returns 返回传入的构造函数
22
+ *
23
+ * ```ts
24
+ * import { createConstructor } from "a-js-tools";
25
+ *
26
+ * type Tom = {
27
+ * a: number
28
+ * }
29
+ *
30
+ * function _Tom (this: TomType): Tom {
31
+ * this.a = 1;
32
+ *
33
+ * return this;
34
+ * }
35
+ *
36
+ * // 逻辑上没有错,但是会造成 ts 显示
37
+ * // 其目标缺少构造签名的 "new" 表达式隐式具有 "any" 类型。ts(7009)
38
+ * const a = new _Tom();
39
+ *
40
+ * const tomConstructor = createConstructor(_tom);
41
+ *
42
+ * const b = new tomConstructor(); // 这时就不会显示错误
43
+ *
44
+ * ```
45
+ *
46
+ */
47
+ export declare function createConstructor<T, Args extends unknown[] = unknown[]>(constructor: (...argumentList: Args) => T): CreateConstructor<T, Args>;
@@ -0,0 +1,42 @@
1
+ /**
2
+ *
3
+ * 构建一个 Constructor 构造函数
4
+ *
5
+ * 接收一个构造函数,然后返回 TS 能识别的构造函数自身
6
+ *
7
+ * 函数本身并没有执行任何逻辑,仅是简单的返回了实参自身
8
+ *
9
+ * 而经过该函数的包装,构造函数成了能够被 TS 识别为可用 new 实例的构造函数
10
+ *
11
+ * @param constructor - 传入一个构造函数
12
+ * @returns 返回传入的构造函数
13
+ *
14
+ * ```ts
15
+ * import { createConstructor } from "a-js-tools";
16
+ *
17
+ * type Tom = {
18
+ * a: number
19
+ * }
20
+ *
21
+ * function _Tom (this: TomType): Tom {
22
+ * this.a = 1;
23
+ *
24
+ * return this;
25
+ * }
26
+ *
27
+ * // 逻辑上没有错,但是会造成 ts 显示
28
+ * // 其目标缺少构造签名的 "new" 表达式隐式具有 "any" 类型。ts(7009)
29
+ * const a = new _Tom();
30
+ *
31
+ * const tomConstructor = createConstructor(_tom);
32
+ *
33
+ * const b = new tomConstructor(); // 这时就不会显示错误
34
+ *
35
+ * ```
36
+ *
37
+ */
38
+ function createConstructor(constructor) {
39
+ return constructor;
40
+ }
41
+
42
+ export { createConstructor };
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var aTypeOfJs = require('a-type-of-js');
4
+
3
5
  /**
4
6
  * 防抖和节流
5
7
  *
@@ -12,7 +14,7 @@
12
14
  * 防抖
13
15
  *
14
16
  * @param callback 回调函数
15
- * @param delay 延迟时间(毫秒),默认 200 (ms)
17
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或包含 this 的配置
16
18
  * @returns 返回的闭包函数
17
19
  * @example
18
20
  *
@@ -25,13 +27,19 @@
25
27
  * }
26
28
  *
27
29
  */
28
- function debounce(callback, delay = 200) {
29
- if (typeof callback !== 'function') {
30
+ function debounce(callback, options = 200) {
31
+ if (!aTypeOfJs.isFunction(callback))
30
32
  throw new TypeError('callback must be a function');
31
- }
32
- if (!isFinite(delay) || delay < 0)
33
+ if (aTypeOfJs.isNumber(options))
34
+ options = {
35
+ delay: options,
36
+ this: null,
37
+ };
38
+ if (aTypeOfJs.isUndefined(options.delay) ||
39
+ !isFinite(options.delay) ||
40
+ options.delay < 0)
33
41
  // 强制转换非数值
34
- delay = 200;
42
+ options.delay = 200;
35
43
  /** 定时器返回的 id */
36
44
  let timeoutId;
37
45
  const clear = () => {
@@ -44,29 +52,36 @@ function debounce(callback, delay = 200) {
44
52
  clear();
45
53
  timeoutId = setTimeout(() => {
46
54
  try {
47
- Reflect.apply(callback, null, args);
55
+ Reflect.apply(callback, options?.this ?? null, args);
48
56
  }
49
57
  catch (error) {
50
58
  console.log('Debounce callback throw an error', error);
51
59
  }
52
- }, Math.max(delay, 5));
53
- };
54
- result.cancel = () => {
55
- clear();
60
+ }, Math.max(options?.delay ?? 5, 5));
56
61
  };
62
+ result.cancel = () => clear();
57
63
  return result;
58
64
  }
59
65
  /**
60
66
  * 节流
61
67
  *
62
68
  * @param callback 回调函数
63
- * @param delay 延迟时间(毫秒),默认 200 (ms)
69
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或设置 this
64
70
  * @returns 返回的闭包函数
65
71
  */
66
- function throttle(callback, delay = 200) {
67
- // 强制转换非数值
68
- if (!isFinite(delay) || (isFinite(delay) && delay < 4))
69
- delay = 200;
72
+ function throttle(callback, options = 200) {
73
+ if (!aTypeOfJs.isFunction(callback))
74
+ throw new TypeError('callback must be a function');
75
+ if (aTypeOfJs.isNumber(options))
76
+ options = {
77
+ delay: options,
78
+ this: null,
79
+ };
80
+ if (aTypeOfJs.isUndefined(options.delay) ||
81
+ !isFinite(options.delay) ||
82
+ options.delay < 0)
83
+ // 强制转换非数值
84
+ options.delay = 200;
70
85
  /** 延迟控制插销 */
71
86
  let inThrottle = false;
72
87
  /** 延迟控制 */
@@ -75,24 +90,22 @@ function throttle(callback, delay = 200) {
75
90
  if (inThrottle)
76
91
  return;
77
92
  try {
78
- Reflect.apply(callback, null, args);
93
+ Reflect.apply(callback, options?.this ?? null, args);
79
94
  }
80
95
  catch (error) {
81
- console.error('Throttle callback throw an error', error);
96
+ console.error('Throttle 执行回调抛出问题', error);
82
97
  }
83
98
  inThrottle = true;
84
- if (timeoutId !== null) {
99
+ if (!aTypeOfJs.isNull(timeoutId))
85
100
  clearTimeout(timeoutId);
86
- }
87
101
  timeoutId = setTimeout(() => {
88
102
  inThrottle = false;
89
103
  timeoutId = null;
90
- }, delay);
104
+ }, Math.max(options?.delay ?? 5, 5));
91
105
  };
92
106
  throttled.cancel = () => {
93
- if (timeoutId !== null) {
107
+ if (!aTypeOfJs.isNull(timeoutId))
94
108
  clearTimeout(timeoutId);
95
- }
96
109
  inThrottle = false;
97
110
  timeoutId = null;
98
111
  };
@@ -15,12 +15,17 @@ export interface DebounceAndThrottleReturnType<F extends Callback> {
15
15
  (...args: Parameters<F>): void;
16
16
  cancel(): void;
17
17
  }
18
+ /** 第二参数 */
19
+ export type debounce_throttle_options = {
20
+ delay?: number;
21
+ this?: null | unknown;
22
+ } | number;
18
23
  /**
19
24
  *
20
25
  * 防抖
21
26
  *
22
27
  * @param callback 回调函数
23
- * @param delay 延迟时间(毫秒),默认 200 (ms)
28
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或包含 this 的配置
24
29
  * @returns 返回的闭包函数
25
30
  * @example
26
31
  *
@@ -33,13 +38,13 @@ export interface DebounceAndThrottleReturnType<F extends Callback> {
33
38
  * }
34
39
  *
35
40
  */
36
- export declare function debounce<F extends (...args: unknown[]) => void>(callback: F, delay?: number): DebounceAndThrottleReturnType<F>;
41
+ export declare function debounce<F extends (...args: unknown[]) => void>(callback: F, options?: debounce_throttle_options): DebounceAndThrottleReturnType<F>;
37
42
  /**
38
43
  * 节流
39
44
  *
40
45
  * @param callback 回调函数
41
- * @param delay 延迟时间(毫秒),默认 200 (ms)
46
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或设置 this
42
47
  * @returns 返回的闭包函数
43
48
  */
44
- export declare function throttle<F extends (...args: unknown[]) => void>(callback: F, delay?: number): DebounceAndThrottleReturnType<F>;
49
+ export declare function throttle<F extends (...args: unknown[]) => void>(callback: F, options?: debounce_throttle_options): DebounceAndThrottleReturnType<F>;
45
50
  export {};
@@ -1,3 +1,5 @@
1
+ import { isFunction, isNumber, isUndefined, isNull } from 'a-type-of-js';
2
+
1
3
  /**
2
4
  * 防抖和节流
3
5
  *
@@ -10,7 +12,7 @@
10
12
  * 防抖
11
13
  *
12
14
  * @param callback 回调函数
13
- * @param delay 延迟时间(毫秒),默认 200 (ms)
15
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或包含 this 的配置
14
16
  * @returns 返回的闭包函数
15
17
  * @example
16
18
  *
@@ -23,13 +25,19 @@
23
25
  * }
24
26
  *
25
27
  */
26
- function debounce(callback, delay = 200) {
27
- if (typeof callback !== 'function') {
28
+ function debounce(callback, options = 200) {
29
+ if (!isFunction(callback))
28
30
  throw new TypeError('callback must be a function');
29
- }
30
- if (!isFinite(delay) || delay < 0)
31
+ if (isNumber(options))
32
+ options = {
33
+ delay: options,
34
+ this: null,
35
+ };
36
+ if (isUndefined(options.delay) ||
37
+ !isFinite(options.delay) ||
38
+ options.delay < 0)
31
39
  // 强制转换非数值
32
- delay = 200;
40
+ options.delay = 200;
33
41
  /** 定时器返回的 id */
34
42
  let timeoutId;
35
43
  const clear = () => {
@@ -42,29 +50,36 @@ function debounce(callback, delay = 200) {
42
50
  clear();
43
51
  timeoutId = setTimeout(() => {
44
52
  try {
45
- Reflect.apply(callback, null, args);
53
+ Reflect.apply(callback, options?.this ?? null, args);
46
54
  }
47
55
  catch (error) {
48
56
  console.log('Debounce callback throw an error', error);
49
57
  }
50
- }, Math.max(delay, 5));
51
- };
52
- result.cancel = () => {
53
- clear();
58
+ }, Math.max(options?.delay ?? 5, 5));
54
59
  };
60
+ result.cancel = () => clear();
55
61
  return result;
56
62
  }
57
63
  /**
58
64
  * 节流
59
65
  *
60
66
  * @param callback 回调函数
61
- * @param delay 延迟时间(毫秒),默认 200 (ms)
67
+ * @param options 延迟时间(毫秒),默认 200 (ms) 或设置 this
62
68
  * @returns 返回的闭包函数
63
69
  */
64
- function throttle(callback, delay = 200) {
65
- // 强制转换非数值
66
- if (!isFinite(delay) || (isFinite(delay) && delay < 4))
67
- delay = 200;
70
+ function throttle(callback, options = 200) {
71
+ if (!isFunction(callback))
72
+ throw new TypeError('callback must be a function');
73
+ if (isNumber(options))
74
+ options = {
75
+ delay: options,
76
+ this: null,
77
+ };
78
+ if (isUndefined(options.delay) ||
79
+ !isFinite(options.delay) ||
80
+ options.delay < 0)
81
+ // 强制转换非数值
82
+ options.delay = 200;
68
83
  /** 延迟控制插销 */
69
84
  let inThrottle = false;
70
85
  /** 延迟控制 */
@@ -73,24 +88,22 @@ function throttle(callback, delay = 200) {
73
88
  if (inThrottle)
74
89
  return;
75
90
  try {
76
- Reflect.apply(callback, null, args);
91
+ Reflect.apply(callback, options?.this ?? null, args);
77
92
  }
78
93
  catch (error) {
79
- console.error('Throttle callback throw an error', error);
94
+ console.error('Throttle 执行回调抛出问题', error);
80
95
  }
81
96
  inThrottle = true;
82
- if (timeoutId !== null) {
97
+ if (!isNull(timeoutId))
83
98
  clearTimeout(timeoutId);
84
- }
85
99
  timeoutId = setTimeout(() => {
86
100
  inThrottle = false;
87
101
  timeoutId = null;
88
- }, delay);
102
+ }, Math.max(options?.delay ?? 5, 5));
89
103
  };
90
104
  throttled.cancel = () => {
91
- if (timeoutId !== null) {
105
+ if (!isNull(timeoutId))
92
106
  clearTimeout(timeoutId);
93
- }
94
107
  inThrottle = false;
95
108
  timeoutId = null;
96
109
  };
@@ -35,14 +35,12 @@ var parse = require('./parse.cjs');
35
35
  *
36
36
  */
37
37
  function autoEscapedRegExp(pattern, options) {
38
- if (!aTypeOfJs.isString(pattern)) {
38
+ if (!aTypeOfJs.isString(pattern))
39
39
  throw new TypeError('pattern must be a 字符串');
40
- }
41
40
  pattern = escapeRegExp.escapeRegExp(pattern);
42
41
  /** 简单转化 */
43
- if (aTypeOfJs.isUndefined(options)) {
42
+ if (aTypeOfJs.isUndefined(options))
44
43
  return new RegExp(pattern);
45
- }
46
44
  options = parse.parse(options);
47
45
  return new RegExp(`${options.start ? '^' : ''}${pattern}${options.end ? '$' : ''}`, options.flags);
48
46
  }
@@ -33,14 +33,12 @@ import { parse } from './parse.mjs';
33
33
  *
34
34
  */
35
35
  function autoEscapedRegExp(pattern, options) {
36
- if (!isString(pattern)) {
36
+ if (!isString(pattern))
37
37
  throw new TypeError('pattern must be a 字符串');
38
- }
39
38
  pattern = escapeRegExp(pattern);
40
39
  /** 简单转化 */
41
- if (isUndefined(options)) {
40
+ if (isUndefined(options))
42
41
  return new RegExp(pattern);
43
- }
44
42
  options = parse(options);
45
43
  return new RegExp(`${options.start ? '^' : ''}${pattern}${options.end ? '$' : ''}`, options.flags);
46
44
  }
@@ -15,19 +15,16 @@ function parse(options) {
15
15
  };
16
16
  }
17
17
  // 处理 flags
18
- if (!aTypeOfJs.isString(options.flags)) {
18
+ if (!aTypeOfJs.isString(options.flags))
19
19
  options.flags = '';
20
- }
21
20
  else {
22
21
  // 需求是保留字符串中的某一部分,使用
23
22
  const regexp = /[migsuy]/g;
24
23
  const matchResult = options.flags.match(regexp);
25
- if (aTypeOfJs.isNull(matchResult)) {
24
+ if (aTypeOfJs.isNull(matchResult))
26
25
  options.flags = '';
27
- }
28
- else {
26
+ else
29
27
  options.flags = [...new Set(matchResult)].join('');
30
- }
31
28
  }
32
29
  return options;
33
30
  }
@@ -13,19 +13,16 @@ function parse(options) {
13
13
  };
14
14
  }
15
15
  // 处理 flags
16
- if (!isString(options.flags)) {
16
+ if (!isString(options.flags))
17
17
  options.flags = '';
18
- }
19
18
  else {
20
19
  // 需求是保留字符串中的某一部分,使用
21
20
  const regexp = /[migsuy]/g;
22
21
  const matchResult = options.flags.match(regexp);
23
- if (isNull(matchResult)) {
22
+ if (isNull(matchResult))
24
23
  options.flags = '';
25
- }
26
- else {
24
+ else
27
25
  options.flags = [...new Set(matchResult)].join('');
28
- }
29
26
  }
30
27
  return options;
31
28
  }
package/src/sleep.cjs CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var aTypeOfJs = require('a-type-of-js');
4
+
3
5
  /**
4
6
  *
5
7
  * ## 线程休息
@@ -28,7 +30,7 @@
28
30
  async function sleep(delay = 1000) {
29
31
  if (!isFinite(delay) || delay < 0)
30
32
  throw new TypeError('delay 应该是一个正常的数值');
31
- if (delay === 0)
33
+ if (aTypeOfJs.isZero(delay))
32
34
  return Promise.resolve();
33
35
  return new Promise(resolve => setTimeout(resolve, delay));
34
36
  }
package/src/sleep.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ import { isZero } from 'a-type-of-js';
2
+
1
3
  /**
2
4
  *
3
5
  * ## 线程休息
@@ -26,7 +28,7 @@
26
28
  async function sleep(delay = 1000) {
27
29
  if (!isFinite(delay) || delay < 0)
28
30
  throw new TypeError('delay 应该是一个正常的数值');
29
- if (delay === 0)
31
+ if (isZero(delay))
30
32
  return Promise.resolve();
31
33
  return new Promise(resolve => setTimeout(resolve, delay));
32
34
  }