pen-it 1.0.8 → 1.0.10
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/README.md +521 -381
- package/dist/array/index.d.ts +0 -68
- package/dist/browser/index.d.ts +0 -54
- package/dist/control/index.d.ts +0 -16
- package/dist/cookie/index.d.ts +0 -15
- package/dist/copy/index.d.ts +1 -20
- package/dist/format/index.d.ts +0 -117
- package/dist/index.cjs +1 -1000
- package/dist/index.js +1 -917
- package/dist/is/index.d.ts +0 -138
- package/dist/storage/index.d.ts +0 -17
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,594 +11,734 @@ pnpm add pen-it
|
|
|
11
11
|
## 使用
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
import { isArray, formatFull, deepClone, unique } from
|
|
14
|
+
import { isArray, formatFull, deepClone, unique } from "pen-it";
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## API
|
|
18
|
+
|
|
19
|
+
### 类型判断
|
|
20
|
+
|
|
17
21
|
---
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
#### isArray(value)
|
|
24
|
+
|
|
25
|
+
> — 判断是否为数组。
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
isArray([1, 2, 3]); // true
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
#### isObject(value)
|
|
32
|
+
|
|
33
|
+
> — 判断是否为对象(不含数组)。
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
isObject({ a: 1 }); // true
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
#### is(val, type)
|
|
40
|
+
|
|
41
|
+
> — 通用类型判断(内部工具)。
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
is([], "Array"); // true
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
#### isFunction(val)
|
|
48
|
+
|
|
49
|
+
> — 判断是否为函数。
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
isFunction(() => {}); // true
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### isAsyncFunction(val)
|
|
56
|
+
|
|
57
|
+
> — 判断是否为异步函数。
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
isAsyncFunction(async () => {}); // true
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### isPromise(value)
|
|
64
|
+
|
|
65
|
+
> — 判断是否为 Promise。
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
isPromise(Promise.resolve()); // true
|
|
69
|
+
```
|
|
20
70
|
|
|
21
|
-
|
|
71
|
+
#### isDate(val)
|
|
22
72
|
|
|
23
|
-
|
|
73
|
+
> — 判断是否为 Date 对象。
|
|
24
74
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
75
|
+
```ts
|
|
76
|
+
isDate(new Date()); // true
|
|
77
|
+
```
|
|
28
78
|
|
|
29
|
-
|
|
79
|
+
#### isNumber(val)
|
|
30
80
|
|
|
31
|
-
|
|
32
|
-
isObject({ a: 1 }) // true
|
|
33
|
-
```
|
|
81
|
+
> — 判断是否为数字(含 NaN/Infinity)。
|
|
34
82
|
|
|
35
|
-
|
|
83
|
+
```ts
|
|
84
|
+
isNumber(42); // true
|
|
85
|
+
```
|
|
36
86
|
|
|
37
|
-
|
|
38
|
-
is([], 'Array') // true
|
|
39
|
-
```
|
|
87
|
+
#### isInt(val)
|
|
40
88
|
|
|
41
|
-
|
|
89
|
+
> — 判断是否为整数。
|
|
42
90
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
91
|
+
```ts
|
|
92
|
+
isInt(42); // true
|
|
93
|
+
```
|
|
46
94
|
|
|
47
|
-
|
|
95
|
+
#### isFloat(val)
|
|
48
96
|
|
|
49
|
-
|
|
50
|
-
isAsyncFunction(async () => {}) // true
|
|
51
|
-
```
|
|
97
|
+
> — 判断是否为浮点数。
|
|
52
98
|
|
|
53
|
-
|
|
99
|
+
```ts
|
|
100
|
+
isFloat(3.14); // true
|
|
101
|
+
```
|
|
54
102
|
|
|
55
|
-
|
|
56
|
-
isPromise(Promise.resolve()) // true
|
|
57
|
-
```
|
|
103
|
+
#### isString(val)
|
|
58
104
|
|
|
59
|
-
|
|
105
|
+
> — 判断是否为字符串。
|
|
60
106
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
107
|
+
```ts
|
|
108
|
+
isString("hello"); // true
|
|
109
|
+
```
|
|
64
110
|
|
|
65
|
-
|
|
111
|
+
#### isBoolean(val)
|
|
66
112
|
|
|
67
|
-
|
|
68
|
-
isNumber(42) // true
|
|
69
|
-
```
|
|
113
|
+
> — 判断是否为布尔值。
|
|
70
114
|
|
|
71
|
-
|
|
115
|
+
```ts
|
|
116
|
+
isBoolean(true); // true
|
|
117
|
+
```
|
|
72
118
|
|
|
73
|
-
|
|
74
|
-
isInt(42) // true
|
|
75
|
-
```
|
|
119
|
+
#### isSymbol(value)
|
|
76
120
|
|
|
77
|
-
|
|
121
|
+
> — 判断是否为 Symbol。
|
|
78
122
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
123
|
+
```ts
|
|
124
|
+
isSymbol(Symbol("foo")); // true
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
#### isPrimitive(value)
|
|
128
|
+
|
|
129
|
+
> — 判断是否为原始类型。
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
isPrimitive(42); // true
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
#### isNull(val)
|
|
136
|
+
|
|
137
|
+
> — 判断是否为 null。
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
isNull(null); // true
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### isDef(val)
|
|
144
|
+
|
|
145
|
+
> — 判断是否不是 undefined。
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
isDef("hello"); // true
|
|
149
|
+
```
|
|
82
150
|
|
|
83
|
-
|
|
151
|
+
#### isUnDef(val)
|
|
84
152
|
|
|
85
|
-
|
|
86
|
-
isString('hello') // true
|
|
87
|
-
```
|
|
153
|
+
> — 判断是否为 undefined。
|
|
88
154
|
|
|
89
|
-
|
|
155
|
+
```ts
|
|
156
|
+
isUnDef(undefined); // true
|
|
157
|
+
```
|
|
90
158
|
|
|
91
|
-
|
|
92
|
-
isBoolean(true) // true
|
|
93
|
-
```
|
|
159
|
+
#### isNullOrUnDef(val)
|
|
94
160
|
|
|
95
|
-
|
|
161
|
+
> — 判断是否为 null 或 undefined。
|
|
96
162
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
163
|
+
```ts
|
|
164
|
+
isNullOrUnDef(null); // true
|
|
165
|
+
```
|
|
100
166
|
|
|
101
|
-
|
|
167
|
+
#### isEmpty(value)
|
|
102
168
|
|
|
103
|
-
|
|
104
|
-
isPrimitive(42) // true
|
|
105
|
-
```
|
|
169
|
+
> — 判断是否为空(完备版:支持 Date/Map/Set 等)。
|
|
106
170
|
|
|
107
|
-
|
|
171
|
+
```ts
|
|
172
|
+
isEmpty(""); // true
|
|
173
|
+
isEmpty([]); // true
|
|
174
|
+
isEmpty({}); // true
|
|
175
|
+
```
|
|
108
176
|
|
|
109
|
-
|
|
110
|
-
isNull(null) // true
|
|
111
|
-
```
|
|
177
|
+
#### isEmptySv(value)
|
|
112
178
|
|
|
113
|
-
|
|
179
|
+
> — 判断是否为空(简化版)。
|
|
114
180
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
181
|
+
```ts
|
|
182
|
+
isEmptySv([]); // true
|
|
183
|
+
```
|
|
118
184
|
|
|
119
|
-
|
|
185
|
+
#### isEqual(x, y)
|
|
120
186
|
|
|
121
|
-
|
|
122
|
-
isUnDef(undefined) // true
|
|
123
|
-
```
|
|
187
|
+
> — 深度相等比较(支持 Date/RegExp)。
|
|
124
188
|
|
|
125
|
-
|
|
189
|
+
```ts
|
|
190
|
+
isEqual({ a: 1 }, { a: 1 }); // true
|
|
191
|
+
```
|
|
126
192
|
|
|
127
|
-
|
|
128
|
-
isNullOrUnDef(null) // true
|
|
129
|
-
```
|
|
193
|
+
#### isHexColor(str)
|
|
130
194
|
|
|
131
|
-
|
|
195
|
+
> — 判断是否为十六进制颜色。
|
|
132
196
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
isEmpty({}) // true
|
|
137
|
-
```
|
|
197
|
+
```ts
|
|
198
|
+
isHexColor("#fff"); // true
|
|
199
|
+
```
|
|
138
200
|
|
|
139
|
-
|
|
201
|
+
#### isValidEmail(email)
|
|
140
202
|
|
|
141
|
-
|
|
142
|
-
isEmptySv([]) // true
|
|
143
|
-
```
|
|
203
|
+
> — 判断是否为有效邮箱。
|
|
144
204
|
|
|
145
|
-
|
|
205
|
+
```ts
|
|
206
|
+
isValidEmail("a@b.com"); // true
|
|
207
|
+
```
|
|
146
208
|
|
|
147
|
-
|
|
148
|
-
isEqual({ a: 1 }, { a: 1 }) // true
|
|
149
|
-
```
|
|
209
|
+
#### isPC()
|
|
150
210
|
|
|
151
|
-
|
|
211
|
+
> — 判断是否为浏览器环境。
|
|
152
212
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
213
|
+
```ts
|
|
214
|
+
isPC(); // true
|
|
215
|
+
```
|
|
156
216
|
|
|
157
|
-
|
|
217
|
+
#### isWindow(val)
|
|
158
218
|
|
|
159
|
-
|
|
160
|
-
isValidEmail('a@b.com') // true
|
|
161
|
-
```
|
|
219
|
+
> — 判断是否为 window 对象。
|
|
162
220
|
|
|
163
|
-
|
|
221
|
+
```ts
|
|
222
|
+
isWindow(window); // true
|
|
223
|
+
```
|
|
164
224
|
|
|
165
|
-
|
|
166
|
-
isPC() // true
|
|
167
|
-
```
|
|
225
|
+
#### isElement(val)
|
|
168
226
|
|
|
169
|
-
|
|
227
|
+
> — 判断是否为 DOM 元素。
|
|
170
228
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
229
|
+
```ts
|
|
230
|
+
isElement(document.body); // true
|
|
231
|
+
```
|
|
174
232
|
|
|
175
|
-
|
|
233
|
+
#### isIOS()
|
|
176
234
|
|
|
177
|
-
|
|
178
|
-
isElement(document.body) // true
|
|
179
|
-
```
|
|
235
|
+
> — 判断设备是否为 iOS。
|
|
180
236
|
|
|
181
|
-
|
|
237
|
+
```ts
|
|
238
|
+
isIOS(); // true
|
|
239
|
+
```
|
|
182
240
|
|
|
183
|
-
|
|
184
|
-
isIOS() // true
|
|
185
|
-
```
|
|
241
|
+
### 时间日期格式化
|
|
186
242
|
|
|
187
243
|
---
|
|
188
244
|
|
|
189
|
-
|
|
245
|
+
#### formatFull(date)
|
|
190
246
|
|
|
191
|
-
|
|
247
|
+
> — 完整日期时间(斜杠分隔)。
|
|
192
248
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
249
|
+
```ts
|
|
250
|
+
formatFull(new Date()); // "2026/06/03 14:30:45"
|
|
251
|
+
```
|
|
196
252
|
|
|
197
|
-
|
|
253
|
+
#### formatFullReplace(date)
|
|
198
254
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
255
|
+
> — 完整日期时间(短横线分隔)。
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
formatFullReplace(new Date()); // "2026-06-03 14:30:45"
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
#### formatYMD(date)
|
|
262
|
+
|
|
263
|
+
> — 中文年月日。
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
formatYMD(new Date()); // "2026年6月3日"
|
|
267
|
+
```
|
|
202
268
|
|
|
203
|
-
|
|
269
|
+
#### formatWeek(date)
|
|
204
270
|
|
|
205
|
-
|
|
206
|
-
formatYMD(new Date()) // "2026年6月3日"
|
|
207
|
-
```
|
|
271
|
+
> — 星期几。
|
|
208
272
|
|
|
209
|
-
|
|
273
|
+
```ts
|
|
274
|
+
formatWeek(new Date()); // "星期三"
|
|
275
|
+
```
|
|
210
276
|
|
|
211
|
-
|
|
212
|
-
formatWeek(new Date()) // "星期三"
|
|
213
|
-
```
|
|
277
|
+
### 数字与货币格式化
|
|
214
278
|
|
|
215
279
|
---
|
|
216
280
|
|
|
217
|
-
|
|
281
|
+
#### formatRmb(value, options)
|
|
282
|
+
|
|
283
|
+
> — 货币格式化(人民币)。
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
formatRmb(1234.56, { type: "zh-CN", currency: "CNY" }); // "¥1,234.56"
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
#### formatNum(value)
|
|
218
290
|
|
|
219
|
-
|
|
291
|
+
> — 千位分隔符。
|
|
220
292
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
293
|
+
```ts
|
|
294
|
+
formatNum(1234567); // "1,234,567"
|
|
295
|
+
```
|
|
224
296
|
|
|
225
|
-
|
|
297
|
+
#### percentCN(value, digit)
|
|
226
298
|
|
|
227
|
-
|
|
228
|
-
formatNum(1234567) // "1,234,567"
|
|
229
|
-
```
|
|
299
|
+
> — 百分比格式化。
|
|
230
300
|
|
|
231
|
-
|
|
301
|
+
```ts
|
|
302
|
+
percentCN(0.1234, 2); // "12.34%"
|
|
303
|
+
```
|
|
232
304
|
|
|
233
|
-
|
|
234
|
-
percentCN(0.1234, 2) // "12.34%"
|
|
235
|
-
```
|
|
305
|
+
#### compactEN(value)
|
|
236
306
|
|
|
237
|
-
|
|
307
|
+
> — 大数简化(英文缩写)。
|
|
238
308
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
309
|
+
```ts
|
|
310
|
+
compactEN(12345); // "12K"
|
|
311
|
+
```
|
|
242
312
|
|
|
243
|
-
|
|
313
|
+
#### compactCN(value)
|
|
244
314
|
|
|
245
|
-
|
|
246
|
-
compactCN(12345) // "1.2万"
|
|
247
|
-
```
|
|
315
|
+
> — 大数简化(中文缩写)。
|
|
248
316
|
|
|
249
|
-
|
|
317
|
+
```ts
|
|
318
|
+
compactCN(12345); // "1.2万"
|
|
319
|
+
```
|
|
250
320
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
321
|
+
#### signed(value, digit)
|
|
322
|
+
|
|
323
|
+
> — 带正负号显示。
|
|
324
|
+
|
|
325
|
+
```ts
|
|
326
|
+
signed(42, 1); // "+42.0"
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 字符串处理
|
|
254
330
|
|
|
255
331
|
---
|
|
256
332
|
|
|
257
|
-
|
|
333
|
+
#### maskPhone(phone)
|
|
258
334
|
|
|
259
|
-
|
|
335
|
+
> — 手机号脱敏(隐藏中间4位)。
|
|
260
336
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
337
|
+
```ts
|
|
338
|
+
maskPhone("13812345678"); // "138****5678"
|
|
339
|
+
```
|
|
264
340
|
|
|
265
|
-
|
|
341
|
+
#### spacePhone(phone)
|
|
266
342
|
|
|
267
|
-
|
|
268
|
-
spacePhone('13812345678') // "138 1234 5678"
|
|
269
|
-
```
|
|
343
|
+
> — 手机号空格分隔。
|
|
270
344
|
|
|
271
|
-
|
|
345
|
+
```ts
|
|
346
|
+
spacePhone("13812345678"); // "138 1234 5678"
|
|
347
|
+
```
|
|
272
348
|
|
|
273
|
-
|
|
274
|
-
capitalize('hello world') // "Hello World"
|
|
275
|
-
```
|
|
349
|
+
#### capitalize(str)
|
|
276
350
|
|
|
277
|
-
|
|
351
|
+
> — 每个单词首字母大写。
|
|
278
352
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
353
|
+
```ts
|
|
354
|
+
capitalize("hello world"); // "Hello World"
|
|
355
|
+
```
|
|
282
356
|
|
|
283
|
-
|
|
357
|
+
#### kebabToCamel(str)
|
|
284
358
|
|
|
285
|
-
|
|
286
|
-
camelToKebab('helloWorld') // "hello-world"
|
|
287
|
-
```
|
|
359
|
+
> — 短横线转小驼峰。
|
|
288
360
|
|
|
289
|
-
|
|
361
|
+
```ts
|
|
362
|
+
kebabToCamel("hello-world"); // "helloWorld"
|
|
363
|
+
```
|
|
290
364
|
|
|
291
|
-
|
|
292
|
-
toCamel('hello_world') // "helloWorld"
|
|
293
|
-
```
|
|
365
|
+
#### camelToKebab(str)
|
|
294
366
|
|
|
295
|
-
|
|
367
|
+
> — 驼峰转短横线。
|
|
296
368
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
369
|
+
```ts
|
|
370
|
+
camelToKebab("helloWorld"); // "hello-world"
|
|
371
|
+
```
|
|
300
372
|
|
|
301
|
-
|
|
373
|
+
#### toCamel(str)
|
|
302
374
|
|
|
303
|
-
|
|
304
|
-
firstLower('Hello') // "hello"
|
|
305
|
-
```
|
|
375
|
+
> — 下划线转驼峰。
|
|
306
376
|
|
|
307
|
-
|
|
377
|
+
```ts
|
|
378
|
+
toCamel("hello_world"); // "helloWorld"
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
#### firstUpper(str)
|
|
382
|
+
|
|
383
|
+
> — 首字母大写。
|
|
384
|
+
|
|
385
|
+
```ts
|
|
386
|
+
firstUpper("hello"); // "Hello"
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
#### firstLower(str)
|
|
308
390
|
|
|
309
|
-
|
|
310
|
-
reverse('hello') // "olleh"
|
|
311
|
-
```
|
|
391
|
+
> — 首字母小写。
|
|
312
392
|
|
|
313
|
-
|
|
393
|
+
```ts
|
|
394
|
+
firstLower("Hello"); // "hello"
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
#### reverse(str)
|
|
398
|
+
|
|
399
|
+
> — 反转字符串。
|
|
314
400
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
401
|
+
```ts
|
|
402
|
+
reverse("hello"); // "olleh"
|
|
403
|
+
```
|
|
318
404
|
|
|
319
|
-
|
|
405
|
+
#### trimAll(str)
|
|
320
406
|
|
|
321
|
-
|
|
322
|
-
truncate('Hello World', 8) // "Hello..."
|
|
323
|
-
```
|
|
407
|
+
> — 去除所有空格。
|
|
324
408
|
|
|
325
|
-
|
|
409
|
+
```ts
|
|
410
|
+
trimAll(" h e l lo "); // "hello"
|
|
411
|
+
```
|
|
326
412
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
413
|
+
#### truncate(str, max, suffix?)
|
|
414
|
+
|
|
415
|
+
> — 超长文本截断。
|
|
416
|
+
|
|
417
|
+
```ts
|
|
418
|
+
truncate("Hello World", 8); // "Hello..."
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### truncateByWords(str, max, suffix?)
|
|
422
|
+
|
|
423
|
+
> — 按字数截断(中文友好)。
|
|
424
|
+
|
|
425
|
+
```ts
|
|
426
|
+
truncateByWords("你好世界欢迎你", 4); // "你好世界..."
|
|
427
|
+
```
|
|
428
|
+
|
|
429
|
+
### 存储
|
|
330
430
|
|
|
331
431
|
---
|
|
332
432
|
|
|
333
|
-
|
|
433
|
+
#### localGet<T>(key)
|
|
434
|
+
|
|
435
|
+
> — 获取 localStorage(自动 JSON 解析)。
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
localGet("user"); // { name: '张三' }
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### localSet(key, value)
|
|
334
442
|
|
|
335
|
-
|
|
443
|
+
> — 设置 localStorage(自动 JSON 序列化)。
|
|
336
444
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
445
|
+
```ts
|
|
446
|
+
localSet("user", { name: "张三" });
|
|
447
|
+
```
|
|
340
448
|
|
|
341
|
-
|
|
449
|
+
#### localRm(key)
|
|
342
450
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
451
|
+
> — 移除指定 localStorage。
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
localRm("user");
|
|
455
|
+
```
|
|
346
456
|
|
|
347
|
-
|
|
457
|
+
#### localClear()
|
|
348
458
|
|
|
349
|
-
|
|
350
|
-
localRm('user')
|
|
351
|
-
```
|
|
459
|
+
> — 清除所有 localStorage。
|
|
352
460
|
|
|
353
|
-
|
|
461
|
+
```ts
|
|
462
|
+
localClear();
|
|
463
|
+
```
|
|
354
464
|
|
|
355
|
-
|
|
356
|
-
localClear()
|
|
357
|
-
```
|
|
465
|
+
### 拷贝
|
|
358
466
|
|
|
359
467
|
---
|
|
360
468
|
|
|
361
|
-
|
|
469
|
+
#### deepClone(obj)
|
|
470
|
+
|
|
471
|
+
> — 递归深拷贝(支持 Date/RegExp/Map/Set/循环引用)。
|
|
362
472
|
|
|
363
|
-
|
|
473
|
+
```ts
|
|
474
|
+
deepClone({ a: 1, b: { c: 2 } });
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
#### deepCloneWithJSON(obj)
|
|
478
|
+
|
|
479
|
+
> — JSON 深拷贝(仅 JSON 安全类型)。
|
|
364
480
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
481
|
+
```ts
|
|
482
|
+
deepCloneWithJSON({ a: 1 });
|
|
483
|
+
```
|
|
368
484
|
|
|
369
|
-
|
|
485
|
+
#### structClone(obj, options?)
|
|
370
486
|
|
|
371
|
-
|
|
372
|
-
deepCloneWithJSON({ a: 1 })
|
|
373
|
-
```
|
|
487
|
+
> — structuredClone 深拷贝(不支持函数/Symbol)。
|
|
374
488
|
|
|
375
|
-
|
|
489
|
+
```ts
|
|
490
|
+
structClone({ a: 1, b: { c: 2 } });
|
|
491
|
+
```
|
|
376
492
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
493
|
+
#### shallowClone(obj)
|
|
494
|
+
|
|
495
|
+
> — 浅拷贝(仅第一层)。
|
|
496
|
+
|
|
497
|
+
```ts
|
|
498
|
+
shallowClone({ a: 1, b: { c: 2 } });
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### 数组
|
|
380
502
|
|
|
381
503
|
---
|
|
382
504
|
|
|
383
|
-
|
|
505
|
+
#### unique(arr)
|
|
384
506
|
|
|
385
|
-
|
|
507
|
+
> — Set 去重。
|
|
386
508
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
509
|
+
```ts
|
|
510
|
+
unique([1, 2, 2, 3]); // [1, 2, 3]
|
|
511
|
+
```
|
|
390
512
|
|
|
391
|
-
|
|
513
|
+
#### uniqueByKey(arr, key)
|
|
392
514
|
|
|
393
|
-
|
|
394
|
-
uniqueByKey([{ id: 1 }, { id: 1 }], 'id')
|
|
395
|
-
```
|
|
515
|
+
> — 对象数组按 key 去重。
|
|
396
516
|
|
|
397
|
-
|
|
517
|
+
```ts
|
|
518
|
+
uniqueByKey([{ id: 1 }, { id: 1 }], "id");
|
|
519
|
+
```
|
|
398
520
|
|
|
399
|
-
|
|
400
|
-
sortNumAsc([3, 1, 2]) // [1, 2, 3]
|
|
401
|
-
```
|
|
521
|
+
#### sortNumAsc(arr)
|
|
402
522
|
|
|
403
|
-
|
|
523
|
+
> — 数值升序。
|
|
404
524
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
525
|
+
```ts
|
|
526
|
+
sortNumAsc([3, 1, 2]); // [1, 2, 3]
|
|
527
|
+
```
|
|
408
528
|
|
|
409
|
-
|
|
529
|
+
#### sortNumDesc(arr)
|
|
410
530
|
|
|
411
|
-
|
|
412
|
-
sortByKey([{ age: 30 }, { age: 20 }], 'age')
|
|
413
|
-
```
|
|
531
|
+
> — 数值降序。
|
|
414
532
|
|
|
415
|
-
|
|
533
|
+
```ts
|
|
534
|
+
sortNumDesc([1, 3, 2]); // [3, 2, 1]
|
|
535
|
+
```
|
|
416
536
|
|
|
417
|
-
|
|
418
|
-
toArray(document.querySelectorAll('div'))
|
|
419
|
-
```
|
|
537
|
+
#### sortByKey(arr, key, order?)
|
|
420
538
|
|
|
421
|
-
|
|
539
|
+
> — 按对象属性排序。
|
|
422
540
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
541
|
+
```ts
|
|
542
|
+
sortByKey([{ age: 30 }, { age: 20 }], "age");
|
|
543
|
+
```
|
|
426
544
|
|
|
427
|
-
|
|
545
|
+
#### toArray(arrayLike)
|
|
428
546
|
|
|
429
|
-
|
|
430
|
-
flatten([1, [2, [3, 4]], 5]) // [1, 2, [3, 4], 5]
|
|
431
|
-
flatten([1, [2, [3, 4]], 5], Infinity) // [1, 2, 3, 4, 5]
|
|
432
|
-
```
|
|
547
|
+
> — 类数组转数组。
|
|
433
548
|
|
|
434
|
-
|
|
549
|
+
```ts
|
|
550
|
+
toArray(document.querySelectorAll("div"));
|
|
551
|
+
```
|
|
435
552
|
|
|
436
|
-
|
|
437
|
-
arrFind([{ id: 1 }, { id: 2 }], 'id', 2) // { id: 2 }
|
|
438
|
-
```
|
|
553
|
+
#### mergeArrays(...arrays)
|
|
439
554
|
|
|
440
|
-
|
|
555
|
+
> — 合并多个数组。
|
|
556
|
+
|
|
557
|
+
```ts
|
|
558
|
+
mergeArrays([1, 2], [3, 4], [5]); // [1, 2, 3, 4, 5]
|
|
559
|
+
```
|
|
441
560
|
|
|
442
|
-
|
|
443
|
-
groupBy([{ type: 'fruit' }, { type: 'vegetable' }], 'type')
|
|
444
|
-
// => { fruit: [...], vegetable: [...] }
|
|
445
|
-
```
|
|
561
|
+
#### flatten(arr, depth?)
|
|
446
562
|
|
|
447
|
-
|
|
563
|
+
> — 多维数组扁平化到指定层级(默认 1 层,传 `Infinity` 完全展开)。
|
|
448
564
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
565
|
+
```ts
|
|
566
|
+
flatten([1, [2, [3, 4]], 5]); // [1, 2, [3, 4], 5]
|
|
567
|
+
flatten([1, [2, [3, 4]], 5], Infinity); // [1, 2, 3, 4, 5]
|
|
568
|
+
```
|
|
452
569
|
|
|
453
|
-
|
|
570
|
+
#### arrFind(arr, key, value)
|
|
454
571
|
|
|
455
|
-
|
|
456
|
-
createRange(5) // [0, 1, 2, 3, 4]
|
|
457
|
-
createRange(3, (i) => i * 2) // [0, 2, 4]
|
|
458
|
-
```
|
|
572
|
+
> — 对象数组中按 key-value 查找第一个匹配项。
|
|
459
573
|
|
|
460
|
-
|
|
574
|
+
```ts
|
|
575
|
+
arrFind([{ id: 1 }, { id: 2 }], "id", 2); // { id: 2 }
|
|
576
|
+
```
|
|
461
577
|
|
|
462
|
-
|
|
578
|
+
#### groupBy(arr, key)
|
|
463
579
|
|
|
464
|
-
|
|
580
|
+
> — 对象数组按指定属性分组。
|
|
581
|
+
|
|
582
|
+
```ts
|
|
583
|
+
groupBy([{ type: "fruit" }, { type: "vegetable" }], "type");
|
|
584
|
+
// => { fruit: [...], vegetable: [...] }
|
|
585
|
+
```
|
|
465
586
|
|
|
466
|
-
|
|
467
|
-
setCookie('token', 'abc123', 30)
|
|
468
|
-
```
|
|
587
|
+
#### filterEmptyValues(obj)
|
|
469
588
|
|
|
470
|
-
|
|
589
|
+
> — 移除对象中值为空(null / undefined / 空字符串)的属性。
|
|
471
590
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
591
|
+
```ts
|
|
592
|
+
filterEmptyValues({ a: 1, b: "", c: null }); // { a: 1 }
|
|
593
|
+
```
|
|
475
594
|
|
|
476
|
-
|
|
595
|
+
#### createRange(length, mapFn?)
|
|
477
596
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
597
|
+
> — 快速生成范围数组。
|
|
598
|
+
|
|
599
|
+
```ts
|
|
600
|
+
createRange(5); // [0, 1, 2, 3, 4]
|
|
601
|
+
createRange(3, (i) => i * 2); // [0, 2, 4]
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
### Cookie
|
|
481
605
|
|
|
482
606
|
---
|
|
483
607
|
|
|
484
|
-
|
|
608
|
+
#### setCookie(name, value, days?)
|
|
485
609
|
|
|
486
|
-
|
|
610
|
+
> — 设置 Cookie(默认7天)。
|
|
487
611
|
|
|
488
|
-
|
|
612
|
+
```ts
|
|
613
|
+
setCookie("token", "abc123", 30);
|
|
614
|
+
```
|
|
489
615
|
|
|
490
|
-
|
|
491
|
-
getUrlParams('?a=1&b=2') // { a: '1', b: '2' }
|
|
492
|
-
```
|
|
616
|
+
#### getCookie(name)
|
|
493
617
|
|
|
494
|
-
|
|
618
|
+
> — 获取 Cookie。
|
|
495
619
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
620
|
+
```ts
|
|
621
|
+
getCookie("token"); // "abc123"
|
|
622
|
+
```
|
|
499
623
|
|
|
500
|
-
|
|
624
|
+
#### delCookie(name)
|
|
501
625
|
|
|
502
|
-
|
|
503
|
-
toQueryString({ a: 1, b: 'hello' }) // "a=1&b=hello"
|
|
504
|
-
```
|
|
626
|
+
> — 删除 Cookie。
|
|
505
627
|
|
|
506
|
-
|
|
628
|
+
```ts
|
|
629
|
+
delCookie("token");
|
|
630
|
+
```
|
|
507
631
|
|
|
508
|
-
|
|
632
|
+
### 浏览器
|
|
509
633
|
|
|
510
|
-
|
|
511
|
-
await copyToClipboard('Hello')
|
|
512
|
-
```
|
|
634
|
+
---
|
|
513
635
|
|
|
514
|
-
|
|
636
|
+
#### getUrlParams(url?)
|
|
515
637
|
|
|
516
|
-
|
|
517
|
-
downloadFile('Hello', 'hello.txt')
|
|
518
|
-
```
|
|
638
|
+
> — 获取 URL 参数对象。
|
|
519
639
|
|
|
520
|
-
|
|
640
|
+
```ts
|
|
641
|
+
getUrlParams("?a=1&b=2"); // { a: '1', b: '2' }
|
|
642
|
+
```
|
|
521
643
|
|
|
522
|
-
|
|
523
|
-
exportJSON({ name: '张三' })
|
|
524
|
-
```
|
|
644
|
+
#### getUrlParam(key, url?)
|
|
525
645
|
|
|
526
|
-
|
|
646
|
+
> — 获取单个 URL 参数。
|
|
527
647
|
|
|
528
|
-
|
|
648
|
+
```ts
|
|
649
|
+
getUrlParam("a"); // "1"
|
|
650
|
+
```
|
|
529
651
|
|
|
530
|
-
|
|
531
|
-
scrollToTop()
|
|
532
|
-
```
|
|
652
|
+
#### toQueryString(params)
|
|
533
653
|
|
|
534
|
-
|
|
654
|
+
> — 对象转 URL 参数字符串。
|
|
535
655
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
656
|
+
```ts
|
|
657
|
+
toQueryString({ a: 1, b: "hello" }); // "a=1&b=hello"
|
|
658
|
+
```
|
|
539
659
|
|
|
540
|
-
|
|
660
|
+
#### copyToClipboard(text)
|
|
541
661
|
|
|
542
|
-
|
|
543
|
-
const off = onScroll(y => console.log(y))
|
|
544
|
-
```
|
|
662
|
+
> — 复制文本到剪贴板(支持降级)。
|
|
545
663
|
|
|
546
|
-
|
|
664
|
+
```ts
|
|
665
|
+
await copyToClipboard("Hello");
|
|
666
|
+
```
|
|
547
667
|
|
|
548
|
-
|
|
668
|
+
#### downloadFile(content, filename, mimeType?)
|
|
549
669
|
|
|
550
|
-
|
|
551
|
-
const cleanup = observeIntersection(
|
|
552
|
-
document.querySelector('.footer')!,
|
|
553
|
-
() => loadMore(10),
|
|
554
|
-
);
|
|
555
|
-
```
|
|
670
|
+
> — 下载文件(Blob)。
|
|
556
671
|
|
|
557
|
-
|
|
672
|
+
```ts
|
|
673
|
+
downloadFile("Hello", "hello.txt");
|
|
674
|
+
```
|
|
558
675
|
|
|
559
|
-
|
|
676
|
+
#### exportJSON(data, filename?)
|
|
560
677
|
|
|
561
|
-
|
|
678
|
+
> — 导出 JSON 为文件。
|
|
562
679
|
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
// => 'c'
|
|
567
|
-
```
|
|
680
|
+
```ts
|
|
681
|
+
exportJSON({ name: "张三" });
|
|
682
|
+
```
|
|
568
683
|
|
|
569
|
-
|
|
684
|
+
#### scrollToTop(behavior?)
|
|
570
685
|
|
|
571
|
-
|
|
572
|
-
const fn = throttle((val: string) => console.log(val), 500)
|
|
573
|
-
fn('a'); fn('b'); fn('c')
|
|
574
|
-
// => 'a',500ms 后输出 'c'
|
|
575
|
-
```
|
|
686
|
+
> — 滚动到顶部(默认平滑)。
|
|
576
687
|
|
|
577
|
-
|
|
688
|
+
```ts
|
|
689
|
+
scrollToTop();
|
|
690
|
+
```
|
|
691
|
+
|
|
692
|
+
#### scrollToBottom(behavior?)
|
|
693
|
+
|
|
694
|
+
> — 滚动到底部(默认平滑)。
|
|
695
|
+
|
|
696
|
+
```ts
|
|
697
|
+
scrollToBottom();
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
#### onScroll(callback)
|
|
578
701
|
|
|
579
|
-
|
|
702
|
+
> — 监听滚动(rAF 节流),返回清理函数。
|
|
703
|
+
|
|
704
|
+
```ts
|
|
705
|
+
const off = onScroll((y) => console.log(y));
|
|
706
|
+
```
|
|
580
707
|
|
|
581
|
-
|
|
708
|
+
#### observeIntersection(target, onEnter, onLeave?, options?)
|
|
582
709
|
|
|
583
|
-
|
|
584
|
-
- **文档** — README 底部新增更新日志模块
|
|
710
|
+
> — 监听元素进入/离开可视区域,返回清理函数。
|
|
585
711
|
|
|
586
|
-
|
|
712
|
+
```ts
|
|
713
|
+
const cleanup = observeIntersection(document.querySelector(".footer")!, () =>
|
|
714
|
+
loadMore(10),
|
|
715
|
+
);
|
|
716
|
+
```
|
|
587
717
|
|
|
588
|
-
|
|
589
|
-
- **浏览器模块** — 新增 `observeIntersection` 可视区域检测(基于 IntersectionObserver)
|
|
718
|
+
### 防抖与节流
|
|
590
719
|
|
|
591
|
-
|
|
720
|
+
---
|
|
592
721
|
|
|
593
|
-
|
|
722
|
+
#### debounce(fn, delay?, options?)
|
|
594
723
|
|
|
595
|
-
|
|
724
|
+
> — 防抖,停止调用 delay 毫秒后才执行。
|
|
596
725
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
726
|
+
```ts
|
|
727
|
+
const fn = debounce((val: string) => console.log(val), 500);
|
|
728
|
+
fn("a");
|
|
729
|
+
fn("b");
|
|
730
|
+
fn("c");
|
|
731
|
+
// => 'c'
|
|
732
|
+
```
|
|
733
|
+
|
|
734
|
+
#### throttle(fn, interval?, options?)
|
|
735
|
+
|
|
736
|
+
> — 节流,固定间隔内最多执行一次。
|
|
737
|
+
|
|
738
|
+
```ts
|
|
739
|
+
const fn = throttle((val: string) => console.log(val), 500);
|
|
740
|
+
fn("a");
|
|
741
|
+
fn("b");
|
|
742
|
+
fn("c");
|
|
743
|
+
// => 'a',500ms 后输出 'c'
|
|
744
|
+
```
|