sculp-js 1.7.1 → 1.8.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.
Files changed (60) hide show
  1. package/README.md +5 -3
  2. package/lib/cjs/array.js +1 -1
  3. package/lib/cjs/async.js +1 -1
  4. package/lib/cjs/base64.js +1 -1
  5. package/lib/cjs/clipboard.js +1 -1
  6. package/lib/cjs/cookie.js +1 -1
  7. package/lib/cjs/date.js +1 -1
  8. package/lib/cjs/dom.js +1 -28
  9. package/lib/cjs/download.js +1 -1
  10. package/lib/cjs/easing.js +1 -1
  11. package/lib/cjs/file.js +1 -1
  12. package/lib/cjs/func.js +1 -1
  13. package/lib/cjs/index.js +3 -4
  14. package/lib/cjs/math.js +1 -1
  15. package/lib/cjs/number.js +1 -1
  16. package/lib/cjs/object.js +190 -24
  17. package/lib/cjs/path.js +1 -1
  18. package/lib/cjs/qs.js +1 -1
  19. package/lib/cjs/random.js +1 -1
  20. package/lib/cjs/string.js +1 -1
  21. package/lib/cjs/tooltip.js +1 -1
  22. package/lib/cjs/tree.js +30 -96
  23. package/lib/cjs/type.js +11 -4
  24. package/lib/cjs/unique.js +1 -1
  25. package/lib/cjs/url.js +1 -1
  26. package/lib/cjs/validator.js +1 -1
  27. package/lib/cjs/variable.js +1 -1
  28. package/lib/cjs/watermark.js +1 -1
  29. package/lib/cjs/we-decode.js +1 -1
  30. package/lib/es/array.js +1 -1
  31. package/lib/es/async.js +1 -1
  32. package/lib/es/base64.js +1 -1
  33. package/lib/es/clipboard.js +1 -1
  34. package/lib/es/cookie.js +1 -1
  35. package/lib/es/date.js +1 -1
  36. package/lib/es/dom.js +2 -27
  37. package/lib/es/download.js +1 -1
  38. package/lib/es/easing.js +1 -1
  39. package/lib/es/file.js +1 -1
  40. package/lib/es/func.js +1 -1
  41. package/lib/es/index.js +5 -5
  42. package/lib/es/math.js +1 -1
  43. package/lib/es/number.js +1 -1
  44. package/lib/es/object.js +190 -25
  45. package/lib/es/path.js +1 -1
  46. package/lib/es/qs.js +1 -1
  47. package/lib/es/random.js +1 -1
  48. package/lib/es/string.js +1 -1
  49. package/lib/es/tooltip.js +1 -1
  50. package/lib/es/tree.js +31 -96
  51. package/lib/es/type.js +11 -5
  52. package/lib/es/unique.js +1 -1
  53. package/lib/es/url.js +1 -1
  54. package/lib/es/validator.js +1 -1
  55. package/lib/es/variable.js +1 -1
  56. package/lib/es/watermark.js +1 -1
  57. package/lib/es/we-decode.js +1 -1
  58. package/lib/index.d.ts +52 -54
  59. package/lib/umd/index.js +228 -149
  60. package/package.json +3 -10
package/lib/es/object.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -81,7 +81,7 @@ function objectPick(obj, keys) {
81
81
  return obj2;
82
82
  }
83
83
  /**
84
- * 对象祛除
84
+ * 对象去除
85
85
  * @param {O} obj
86
86
  * @param {K} keys
87
87
  * @returns {Pick<O, ArrayElements<K>>}
@@ -166,6 +166,13 @@ function objectFill(source, target, fillable) {
166
166
  });
167
167
  return source;
168
168
  }
169
+ /**
170
+ * 获取对象指定层级下的属性值(现在可用ES6+的可选链?.来替代)
171
+ * @param {AnyObject} obj
172
+ * @param {string} path
173
+ * @param {boolean} strict
174
+ * @returns
175
+ */
169
176
  function objectGet(obj, path, strict = false) {
170
177
  path = path.replace(/\[(\w+)\]/g, '.$1');
171
178
  path = path.replace(/^\./, '');
@@ -196,12 +203,16 @@ function objectGet(obj, path, strict = false) {
196
203
  }
197
204
  /**
198
205
  * 深拷贝堪称完全体 即:任何类型的数据都会被深拷贝
206
+ *
207
+ * 包含对null、原始值、对象循环引用的处理
208
+ *
209
+ * 对Map、Set、ArrayBuffer、Date、RegExp、Array、Object及原型链属性方法执行深拷贝
199
210
  * @param {T} source
200
211
  * @param {WeakMap} map
201
212
  * @returns {T}
202
213
  */
203
214
  function cloneDeep(source, map = new WeakMap()) {
204
- // 处理原始类型(非对象/数组)和 null/undefined
215
+ // 处理原始类型和 null/undefined
205
216
  if (source === null || typeof source !== 'object') {
206
217
  return source;
207
218
  }
@@ -209,28 +220,33 @@ function cloneDeep(source, map = new WeakMap()) {
209
220
  if (map.has(source)) {
210
221
  return map.get(source);
211
222
  }
212
- // 处理 Date 类型
223
+ // 处理 ArrayBuffer
224
+ if (source instanceof ArrayBuffer) {
225
+ const copy = new ArrayBuffer(source.byteLength);
226
+ new Uint8Array(copy).set(new Uint8Array(source));
227
+ map.set(source, copy);
228
+ return copy;
229
+ }
230
+ // 处理 DataView 和 TypedArray (Uint8Array 等)
231
+ if (ArrayBuffer.isView(source)) {
232
+ const constructor = source.constructor;
233
+ const bufferCopy = cloneDeep(source.buffer, map);
234
+ return new constructor(bufferCopy, source.byteOffset, source.length);
235
+ }
236
+ // 处理 Date 对象
213
237
  if (source instanceof Date) {
214
238
  const copy = new Date(source.getTime());
215
239
  map.set(source, copy);
216
240
  return copy;
217
241
  }
218
- // 处理 RegExp 类型
242
+ // 处理 RegExp 对象
219
243
  if (source instanceof RegExp) {
220
244
  const copy = new RegExp(source.source, source.flags);
245
+ copy.lastIndex = source.lastIndex; // 保留匹配状态
221
246
  map.set(source, copy);
222
247
  return copy;
223
248
  }
224
- // 处理数组类型
225
- if (Array.isArray(source)) {
226
- const copy = [];
227
- map.set(source, copy);
228
- for (const item of source) {
229
- copy.push(cloneDeep(item, map));
230
- }
231
- return copy;
232
- }
233
- // 处理 Map 类型
249
+ // 处理 Map
234
250
  if (source instanceof Map) {
235
251
  const copy = new Map();
236
252
  map.set(source, copy);
@@ -239,7 +255,7 @@ function cloneDeep(source, map = new WeakMap()) {
239
255
  });
240
256
  return copy;
241
257
  }
242
- // 处理 Set 类型
258
+ // 处理 Set
243
259
  if (source instanceof Set) {
244
260
  const copy = new Set();
245
261
  map.set(source, copy);
@@ -248,21 +264,170 @@ function cloneDeep(source, map = new WeakMap()) {
248
264
  });
249
265
  return copy;
250
266
  }
251
- // 处理 ArrayBuffer 类型
252
- if (source instanceof ArrayBuffer) {
253
- const copy = new ArrayBuffer(source.byteLength);
254
- new Uint8Array(copy).set(new Uint8Array(source));
267
+ // 处理数组 (包含稀疏数组)
268
+ if (Array.isArray(source)) {
269
+ const copy = Array.from({ length: source.length });
255
270
  map.set(source, copy);
271
+ // 克隆所有有效索引
272
+ for (let i = 0; i < source.length; i++) {
273
+ if (i in source) {
274
+ // 保留空位
275
+ copy[i] = cloneDeep(source[i], map);
276
+ }
277
+ }
278
+ // 克隆数组的自定义属性
279
+ const descriptors = Object.getOwnPropertyDescriptors(source);
280
+ for (const key of Reflect.ownKeys(descriptors)) {
281
+ Object.defineProperty(copy, key, {
282
+ ...descriptors[key],
283
+ value: cloneDeep(descriptors[key].value, map)
284
+ });
285
+ }
256
286
  return copy;
257
287
  }
258
- // 处理普通对象(包括原型链继承)
288
+ // 处理普通对象和类实例
259
289
  const copy = Object.create(Object.getPrototypeOf(source));
260
290
  map.set(source, copy);
261
- for (const key of Reflect.ownKeys(source)) {
262
- const value = source[key];
263
- copy[key] = cloneDeep(value, map);
291
+ const descriptors = Object.getOwnPropertyDescriptors(source);
292
+ for (const key of Reflect.ownKeys(descriptors)) {
293
+ const descriptor = descriptors[key];
294
+ if ('value' in descriptor) {
295
+ // 克隆数据属性
296
+ descriptor.value = cloneDeep(descriptor.value, map);
297
+ }
298
+ else {
299
+ // 处理访问器属性 (getter/setter)
300
+ if (descriptor.get) {
301
+ descriptor.get = cloneDeep(descriptor.get, map);
302
+ }
303
+ if (descriptor.set) {
304
+ descriptor.set = cloneDeep(descriptor.set, map);
305
+ }
306
+ }
307
+ Object.defineProperty(copy, key, descriptor);
264
308
  }
265
309
  return copy;
266
310
  }
311
+ /**
312
+ * 比较两值是否相等,适用所有数据类型
313
+ * @param {Comparable} a
314
+ * @param {Comparable} b
315
+ * @returns {boolean}
316
+ */
317
+ function isEqual(a, b) {
318
+ return deepEqual(a, b);
319
+ }
320
+ function deepEqual(a, b, compared = new WeakMap()) {
321
+ // 相同值快速返回
322
+ if (Object.is(a, b))
323
+ return true;
324
+ // 类型不同直接返回false
325
+ const typeA = Object.prototype.toString.call(a);
326
+ const typeB = Object.prototype.toString.call(b);
327
+ if (typeA !== typeB)
328
+ return false;
329
+ // 只缓存对象类型
330
+ if (isObject(a) && isObject(b)) {
331
+ if (compared.has(a))
332
+ return compared.get(a) === b;
333
+ compared.set(a, b);
334
+ compared.set(b, a);
335
+ }
336
+ // 处理特殊对象类型
337
+ switch (typeA) {
338
+ case '[object Date]':
339
+ return a.getTime() === b.getTime();
340
+ case '[object RegExp]':
341
+ return a.toString() === b.toString();
342
+ case '[object Map]':
343
+ return compareMap(a, b, compared);
344
+ case '[object Set]':
345
+ return compareSet(a, b, compared);
346
+ case '[object ArrayBuffer]':
347
+ return compareArrayBuffer(a, b);
348
+ case '[object DataView]':
349
+ return compareDataView(a, b, compared);
350
+ case '[object Int8Array]':
351
+ case '[object Uint8Array]':
352
+ case '[object Uint8ClampedArray]':
353
+ case '[object Int16Array]':
354
+ case '[object Uint16Array]':
355
+ case '[object Int32Array]':
356
+ case '[object Uint32Array]':
357
+ case '[object Float32Array]':
358
+ case '[object Float64Array]':
359
+ return compareTypedArray(a, b, compared);
360
+ case '[object Object]':
361
+ return compareObjects(a, b, compared);
362
+ case '[object Array]':
363
+ return compareArrays(a, b, compared);
364
+ }
365
+ return false;
366
+ }
367
+ // 辅助比较函数
368
+ function compareMap(a, b, compared) {
369
+ if (a.size !== b.size)
370
+ return false;
371
+ for (const [key, value] of a) {
372
+ if (!b.has(key) || !deepEqual(value, b.get(key), compared))
373
+ return false;
374
+ }
375
+ return true;
376
+ }
377
+ function compareSet(a, b, compared) {
378
+ if (a.size !== b.size)
379
+ return false;
380
+ for (const value of a) {
381
+ let found = false;
382
+ for (const bValue of b) {
383
+ if (deepEqual(value, bValue, compared)) {
384
+ found = true;
385
+ break;
386
+ }
387
+ }
388
+ if (!found)
389
+ return false;
390
+ }
391
+ return true;
392
+ }
393
+ function compareArrayBuffer(a, b) {
394
+ if (a.byteLength !== b.byteLength)
395
+ return false;
396
+ return new DataView(a).getInt32(0) === new DataView(b).getInt32(0);
397
+ }
398
+ function compareDataView(a, b, compared) {
399
+ return a.byteLength === b.byteLength && deepEqual(new Uint8Array(a.buffer), new Uint8Array(b.buffer), compared);
400
+ }
401
+ function compareTypedArray(a, b, compared) {
402
+ return a.byteLength === b.byteLength && deepEqual(Array.from(a), Array.from(b), compared);
403
+ }
404
+ function compareObjects(a, b, compared) {
405
+ const keysA = Reflect.ownKeys(a);
406
+ const keysB = Reflect.ownKeys(b);
407
+ if (keysA.length !== keysB.length)
408
+ return false;
409
+ for (const key of keysA) {
410
+ if (!keysB.includes(key))
411
+ return false;
412
+ if (!deepEqual(a[key], b[key], compared))
413
+ return false;
414
+ }
415
+ // 原型链比较
416
+ return Object.getPrototypeOf(a) === Object.getPrototypeOf(b);
417
+ }
418
+ function compareArrays(a, b, compared) {
419
+ // 增加有效索引检查
420
+ const keysA = Object.keys(a).map(Number);
421
+ const keysB = Object.keys(b).map(Number);
422
+ if (keysA.length !== keysB.length)
423
+ return false;
424
+ // 递归比较每个元素
425
+ for (let i = 0; i < a.length; i++) {
426
+ if (!deepEqual(a[i], b[i], compared))
427
+ return false;
428
+ }
429
+ // 比较数组对象的其他属性
430
+ return compareObjects(a, b, compared);
431
+ }
267
432
 
268
- export { cloneDeep, isPlainObject, objectAssign, objectEach, objectEachAsync, objectFill, objectGet, objectMap, objectAssign as objectMerge, objectOmit, objectPick };
433
+ export { cloneDeep, isEqual, isPlainObject, objectAssign, objectEach, objectEachAsync, objectFill, objectGet, objectMap, objectAssign as objectMerge, objectOmit, objectPick };
package/lib/es/path.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/qs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/random.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/string.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/tooltip.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/tree.js CHANGED
@@ -1,16 +1,18 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
6
6
 
7
7
  import { objectOmit } from './object.js';
8
+ import { objectHas, isEmpty } from './type.js';
8
9
 
9
10
  const defaultFieldOptions = { keyField: 'key', childField: 'children', pidField: 'pid' };
10
11
  const defaultSearchTreeOptions = {
11
12
  childField: 'children',
12
13
  nameField: 'name',
13
- ignoreEmptyChild: false
14
+ removeEmptyChild: false,
15
+ ignoreCase: true
14
16
  };
15
17
  /**
16
18
  * 深度优先遍历函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
@@ -67,7 +69,9 @@ function forEachDeep(tree, iterator, children = 'children', isReverse = false) {
67
69
  walk(tree, null);
68
70
  }
69
71
  /**
70
- * 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
72
+ * 创建一个新数组, 深度优先遍历的Map函数(支持continue和break操作), 可用于insert tree item 和 remove tree item
73
+ *
74
+ * 可遍历任何带有 length 属性和数字键的类数组对象
71
75
  * @param {ArrayLike<V>} tree 树形数据
72
76
  * @param {Function} iterator 迭代函数, 返回值为true时continue, 返回值为false时break
73
77
  * @param {string} children 定制子元素的key
@@ -167,91 +171,6 @@ function searchTreeById(tree, nodeId, config) {
167
171
  };
168
172
  return getIds(toFlatArray(tree));
169
173
  }
170
- /**
171
- * 使用迭代函数转换数组
172
- * @param {T} array
173
- * @param {Function} callback 迭代函数
174
- * @returns {Array}
175
- */
176
- function flatMap(array, callback) {
177
- const result = [];
178
- array.forEach((value, index) => {
179
- result.push(...callback(value, index, array));
180
- });
181
- return result;
182
- }
183
- /**
184
- * 根据 idProp 与 parentIdProp 从对象数组中构建对应的树
185
- * 当 A[parentIdProp] === B[idProp] 时,对象A会被移动到对象B的children。
186
- * 当一个对象的 parentIdProp 不与其他对象的 idProp 字段相等时,该对象被作为树的顶层节点
187
- * @param {string} idProp 元素ID
188
- * @param {string} parentIdProp 父元素ID
189
- * @param {object[]} items 一维数组
190
- * @returns {WithChildren<T>[]} 树
191
- * @example
192
- * const array = [
193
- * { id: 'node-1', parent: 'root' },
194
- * { id: 'node-2', parent: 'root' },
195
- * { id: 'node-3', parent: 'node-2' },
196
- * { id: 'node-4', parent: 'node-2' },
197
- * { id: 'node-5', parent: 'node-4' },
198
- * ]
199
- * const tree = buildTree('id', 'parent', array)
200
- * expect(tree).toEqual([
201
- * { id: 'node-1', parent: 'root' },
202
- * {
203
- * id: 'node-2',
204
- * parent: 'root',
205
- * children: [
206
- * { id: 'node-3', parent: 'node-2' },
207
- * {
208
- * id: 'node-4',
209
- * parent: 'node-2',
210
- * children: [{ id: 'node-5', parent: 'node-4' }],
211
- * },
212
- * ],
213
- * },
214
- * ])
215
- */
216
- function buildTree(idProp, parentIdProp, items) {
217
- const wrapperMap = new Map();
218
- const ensure = (id) => {
219
- if (wrapperMap.has(id)) {
220
- return wrapperMap.get(id);
221
- }
222
- //@ts-ignore
223
- const wrapper = { id, parent: null, item: null, children: [] };
224
- wrapperMap.set(id, wrapper);
225
- return wrapper;
226
- };
227
- for (const item of items) {
228
- const parentWrapper = ensure(item[parentIdProp]);
229
- const itemWrapper = ensure(item[idProp]);
230
- //@ts-ignore
231
- itemWrapper.parent = parentWrapper;
232
- //@ts-ignore
233
- parentWrapper.children.push(itemWrapper);
234
- //@ts-ignore
235
- itemWrapper.item = item;
236
- }
237
- const topLevelWrappers = flatMap(Array.from(wrapperMap.values()).filter(wrapper => wrapper.parent === null), wrapper => wrapper.children);
238
- return unwrapRecursively(topLevelWrappers);
239
- function unwrapRecursively(wrapperArray) {
240
- const result = [];
241
- for (const wrapper of wrapperArray) {
242
- if (wrapper.children.length === 0) {
243
- result.push(wrapper.item);
244
- }
245
- else {
246
- result.push({
247
- ...wrapper.item,
248
- children: unwrapRecursively(wrapper.children)
249
- });
250
- }
251
- }
252
- return result;
253
- }
254
- }
255
174
  /**
256
175
  * 扁平化数组转换成树(效率高于buildTree)
257
176
  * @param {any[]} list
@@ -303,20 +222,36 @@ function flatTree(treeList, options = defaultFieldOptions) {
303
222
  }
304
223
  /**
305
224
  * 模糊搜索函数,返回包含搜索字符的节点及其祖先节点, 适用于树型组件的字符过滤功能
306
- * @param {any[]} nodes
307
- * @param {string} query
225
+ * 以下搜索条件二选一,按先后优先级处理:
226
+ * 1. 过滤函数filter, 返回true/false
227
+ * 2. 匹配关键词,支持是否启用忽略大小写来判断
228
+ *
229
+ * 有以下特性:
230
+ * 1. 可配置removeEmptyChild字段,来决定是否移除搜索结果中的空children字段
231
+ * 2. 若无任何过滤条件或keyword模式匹配且keyword为空串,返回原对象;其他情况返回新数组
232
+ * @param {V[]} nodes
233
+ * @param {IFilterCondition} filterCondition
308
234
  * @param {ISearchTreeOpts} options
309
- * @returns {any[]}
235
+ * @returns {V[]}
310
236
  */
311
- function fuzzySearchTree(nodes, query, options = defaultSearchTreeOptions) {
237
+ function fuzzySearchTree(nodes, filterCondition, options = defaultSearchTreeOptions) {
238
+ if (!objectHas(filterCondition, 'filter') &&
239
+ (!objectHas(filterCondition, 'keyword') || isEmpty(filterCondition.keyword))) {
240
+ return nodes;
241
+ }
312
242
  const result = [];
313
243
  for (const node of nodes) {
314
244
  // 递归检查子节点是否匹配
315
245
  const matchedChildren = node[options.childField] && node[options.childField].length > 0
316
- ? fuzzySearchTree(node[options.childField] || [], query, options)
246
+ ? fuzzySearchTree(node[options.childField] || [], filterCondition, options)
317
247
  : [];
318
248
  // 检查当前节点是否匹配或者有匹配的子节点
319
- if (node[options.nameField].toLowerCase().includes(query.toLowerCase()) || matchedChildren.length > 0) {
249
+ if ((objectHas(filterCondition, 'filter')
250
+ ? filterCondition.filter(node)
251
+ : !options.ignoreCase
252
+ ? node[options.nameField].includes(filterCondition.keyword)
253
+ : node[options.nameField].toLowerCase().includes(filterCondition.keyword.toLowerCase())) ||
254
+ matchedChildren.length > 0) {
320
255
  // 将当前节点加入结果中
321
256
  if (node[options.childField]) {
322
257
  if (matchedChildren.length > 0) {
@@ -325,7 +260,7 @@ function fuzzySearchTree(nodes, query, options = defaultSearchTreeOptions) {
325
260
  [options.childField]: matchedChildren // 包含匹配的子节点
326
261
  });
327
262
  }
328
- else if (options.ignoreEmptyChild) {
263
+ else if (options.removeEmptyChild) {
329
264
  node[options.childField] && delete node[options.childField];
330
265
  result.push({
331
266
  ...node
@@ -349,4 +284,4 @@ function fuzzySearchTree(nodes, query, options = defaultSearchTreeOptions) {
349
284
  return result;
350
285
  }
351
286
 
352
- export { buildTree, flatTree, forEachDeep, formatTree, fuzzySearchTree, mapDeep, searchTreeById };
287
+ export { flatTree, forEachDeep, formatTree, fuzzySearchTree, mapDeep, searchTreeById };
package/lib/es/type.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -30,11 +30,17 @@ function arrayLike(any) {
30
30
  return objectHas(any, 'length');
31
31
  }
32
32
  /**
33
- * 判断任意值的数据类型
33
+ * 判断任意值的数据类型,检查非对象时不如typeof、instanceof的性能高
34
+ *
35
+ * 当检查类对象时是不可靠的,对象可以通过定义 Symbol.toStringTag 属性来更改检查结果
36
+ *
37
+ * 详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString
34
38
  * @param {unknown} any
35
- * @returns {string}
39
+ * @returns
36
40
  */
37
- const typeIs = (any) => Object.prototype.toString.call(any).slice(8, -1);
41
+ function typeIs(any) {
42
+ return Object.prototype.toString.call(any).slice(8, -1);
43
+ }
38
44
  // 基本数据类型判断
39
45
  const isString = (any) => typeof any === 'string';
40
46
  const isBoolean = (any) => typeof any === 'boolean';
@@ -114,4 +120,4 @@ function isEmpty(value) {
114
120
  return !Object.keys(value).length;
115
121
  }
116
122
 
117
- export { arrayLike, typeIs as default, isArray, isBigInt, isBoolean, isDate, isEmpty, isError, isFunction, isJsonString, isNaN, isNull, isNullOrUnDef, isNumber, isObject, isPrimitive, isRegExp, isString, isSymbol, isUndefined, objectHas, typeIs };
123
+ export { arrayLike, typeIs as default, isArray, isBigInt, isBoolean, isDate, isEmpty, isError, isFunction, isJsonString, isNaN, isNull, isNullOrUnDef, isNullOrUnDef as isNullish, isNumber, isObject, isPrimitive, isRegExp, isString, isSymbol, isUndefined, objectHas, typeIs };
package/lib/es/unique.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
package/lib/es/url.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * sculp-js v1.7.0
2
+ * sculp-js v1.8.0
3
3
  * (c) 2023-present chandq
4
4
  * Released under the MIT License.
5
5
  */