@codady/utils 0.0.12 → 0.0.14
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/CHANGELOG.md +36 -0
- package/dist/utils.cjs.js +60 -10
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +60 -10
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +60 -10
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/modules.js +3 -1
- package/modules.ts +3 -1
- package/package.json +1 -1
- package/src/copyObjectWithSymbol.js +26 -0
- package/src/copyObjectWithSymbol.ts +28 -0
- package/src/deepClone.js +14 -2
- package/src/deepClone.ts +36 -14
- package/src/getDataType - /345/211/257/346/234/254.js" +38 -0
- package/src/isEmpty - /345/211/257/346/234/254.js" +45 -0
- package/src/isEmpty.js +45 -0
- package/src/isEmpty.ts +44 -0
- package/src/shallowCopy.js +40 -8
- package/src/shallowCopy.ts +47 -9
package/modules.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Last modified: 2025/12/25
|
|
2
|
+
* Last modified: 2025/12/25 14:29:40
|
|
3
3
|
*/
|
|
4
4
|
'use strict';
|
|
5
5
|
import deepClone from './src/deepClone';
|
|
@@ -15,6 +15,7 @@ import wrapSetMethods from './src/wrapSetMethods';
|
|
|
15
15
|
import wrapMapMethods from './src/wrapMapMethods';
|
|
16
16
|
import deepMerge from './src/deepMerge';
|
|
17
17
|
import shallowCopy from './src/shallowCopy';
|
|
18
|
+
import copyObjectWithSymbol from './src/copyObjectWithSymbol';
|
|
18
19
|
const utils = {
|
|
19
20
|
//executeStr,
|
|
20
21
|
getDataType,
|
|
@@ -32,5 +33,6 @@ const utils = {
|
|
|
32
33
|
getUniqueId,
|
|
33
34
|
deepMerge,
|
|
34
35
|
shallowCopy,
|
|
36
|
+
copyObjectWithSymbol,
|
|
35
37
|
};
|
|
36
38
|
export default utils;
|
package/modules.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Last modified: 2025/12/25
|
|
2
|
+
* Last modified: 2025/12/25 14:29:40
|
|
3
3
|
*/
|
|
4
4
|
'use strict'
|
|
5
5
|
import deepClone from './src/deepClone';
|
|
@@ -23,6 +23,7 @@ import deepMergeObjects from './src/deepMergeObjects';
|
|
|
23
23
|
import deepMergeSets from './src/deepMergeSets';
|
|
24
24
|
import deepEqual from './src/deepEqual';
|
|
25
25
|
import shallowCopy from './src/shallowCopy';
|
|
26
|
+
import copyObjectWithSymbol from './src/copyObjectWithSymbol';
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
|
|
@@ -43,6 +44,7 @@ const utils = {
|
|
|
43
44
|
getUniqueId,
|
|
44
45
|
deepMerge,
|
|
45
46
|
shallowCopy,
|
|
47
|
+
copyObjectWithSymbol,
|
|
46
48
|
|
|
47
49
|
};
|
|
48
50
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codady/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"author": "AXUI Development Team",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "This is a set of general-purpose JavaScript utility functions developed by the AXUI team. All functions are pure and do not involve CSS or other third-party libraries. They are suitable for any web front-end environment.",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shallow copies an object, including both string keys and Symbol keys.
|
|
3
|
+
* 浅复制对象,包括字符串键和Symbol键
|
|
4
|
+
*
|
|
5
|
+
* @param data The source object to copy
|
|
6
|
+
* @returns A new object with all enumerable properties (both string and Symbol keys)
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const sym = Symbol('test');
|
|
10
|
+
* const obj = { a: 1, [sym]: 'symbol value' };
|
|
11
|
+
* const copy = copyObjectWithSymbol(obj);
|
|
12
|
+
* // copy = { a: 1, [Symbol('test')]: 'symbol value' }
|
|
13
|
+
*/
|
|
14
|
+
const copyObjectWithSymbol = (data) => {
|
|
15
|
+
if (!data || typeof data !== 'object') {
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
// Ensure the object type includes string and symbol keys
|
|
19
|
+
const obj = data, symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
|
|
20
|
+
acc[sym] = obj[sym];
|
|
21
|
+
return acc;
|
|
22
|
+
}, {});
|
|
23
|
+
// Shallow copy the object and include the Symbol properties
|
|
24
|
+
return { ...obj, ...symbolProperties };
|
|
25
|
+
};
|
|
26
|
+
export default copyObjectWithSymbol;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shallow copies an object, including both string keys and Symbol keys.
|
|
3
|
+
* 浅复制对象,包括字符串键和Symbol键
|
|
4
|
+
*
|
|
5
|
+
* @param data The source object to copy
|
|
6
|
+
* @returns A new object with all enumerable properties (both string and Symbol keys)
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const sym = Symbol('test');
|
|
10
|
+
* const obj = { a: 1, [sym]: 'symbol value' };
|
|
11
|
+
* const copy = copyObjectWithSymbol(obj);
|
|
12
|
+
* // copy = { a: 1, [Symbol('test')]: 'symbol value' }
|
|
13
|
+
*/
|
|
14
|
+
const copyObjectWithSymbol = <T extends Record<string | symbol, any>>(data: T): T => {
|
|
15
|
+
if (!data || typeof data !== 'object') {
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
// Ensure the object type includes string and symbol keys
|
|
19
|
+
const obj = data as { [key: string | symbol]: any },
|
|
20
|
+
symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc: { [key: symbol]: any }, sym: symbol) => {
|
|
21
|
+
acc[sym] = obj[sym];
|
|
22
|
+
return acc;
|
|
23
|
+
}, {});
|
|
24
|
+
|
|
25
|
+
// Shallow copy the object and include the Symbol properties
|
|
26
|
+
return { ...obj, ...symbolProperties } as T;
|
|
27
|
+
}
|
|
28
|
+
export default copyObjectWithSymbol;
|
package/src/deepClone.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since Last modified: 2025/12/
|
|
2
|
+
* @since Last modified: 2025/12/26 09:45:33
|
|
3
3
|
* Deep clone an array, object, or other cloneable data types.
|
|
4
4
|
*
|
|
5
5
|
* Features:
|
|
@@ -108,18 +108,26 @@ const deepClone = (data, options = {}) => {
|
|
|
108
108
|
input: data,
|
|
109
109
|
type: dataType,
|
|
110
110
|
cloned: result !== data,
|
|
111
|
+
parent: opts.parent
|
|
111
112
|
});
|
|
112
113
|
return result;
|
|
113
114
|
}
|
|
114
115
|
// If interceptor returns null/undefined, continue with normal cloning process
|
|
115
116
|
}
|
|
116
117
|
// Callback before cloning
|
|
117
|
-
opts.onBeforeClone?.(
|
|
118
|
+
opts.onBeforeClone?.({
|
|
119
|
+
input: data,
|
|
120
|
+
type: dataType,
|
|
121
|
+
parent: opts.parent
|
|
122
|
+
});
|
|
118
123
|
let newData, cloned = true;
|
|
119
124
|
if (dataType === 'Object' && opts.cloneObject) {
|
|
120
125
|
const newObj = {}, symbols = Object.getOwnPropertySymbols(data);
|
|
126
|
+
//存储parent对象,在下一次深复制时使用
|
|
127
|
+
opts.parent = data;
|
|
121
128
|
// Clone regular properties
|
|
122
129
|
for (const key in data) {
|
|
130
|
+
//临时保存父对象
|
|
123
131
|
newObj[key] = deepClone(data[key], opts);
|
|
124
132
|
}
|
|
125
133
|
// Clone Symbol properties
|
|
@@ -131,10 +139,12 @@ const deepClone = (data, options = {}) => {
|
|
|
131
139
|
newData = newObj;
|
|
132
140
|
}
|
|
133
141
|
else if (dataType === 'Array' && opts.cloneArray) {
|
|
142
|
+
opts.parent = data;
|
|
134
143
|
newData = data.map(item => deepClone(item, opts));
|
|
135
144
|
}
|
|
136
145
|
else if (dataType === 'Map' && opts.cloneMap) {
|
|
137
146
|
const newMap = new Map();
|
|
147
|
+
opts.parent = data;
|
|
138
148
|
for (const [key, value] of data) {
|
|
139
149
|
// Both Map keys and values need deep cloning
|
|
140
150
|
newMap.set(deepClone(key, opts), deepClone(value, opts));
|
|
@@ -143,6 +153,7 @@ const deepClone = (data, options = {}) => {
|
|
|
143
153
|
}
|
|
144
154
|
else if (dataType === 'Set' && opts.cloneSet) {
|
|
145
155
|
const newSet = new Set();
|
|
156
|
+
opts.parent = data;
|
|
146
157
|
for (const value of data) {
|
|
147
158
|
// Set values need deep cloning
|
|
148
159
|
newSet.add(deepClone(value, opts));
|
|
@@ -172,6 +183,7 @@ const deepClone = (data, options = {}) => {
|
|
|
172
183
|
input: data,
|
|
173
184
|
type: dataType,
|
|
174
185
|
cloned,
|
|
186
|
+
parent: opts.parent
|
|
175
187
|
});
|
|
176
188
|
return newData;
|
|
177
189
|
};
|
package/src/deepClone.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since Last modified: 2025/12/
|
|
2
|
+
* @since Last modified: 2025/12/26 09:45:33
|
|
3
3
|
* Deep clone an array, object, or other cloneable data types.
|
|
4
4
|
*
|
|
5
5
|
* Features:
|
|
@@ -96,16 +96,24 @@ export interface DeepCloneOptions {
|
|
|
96
96
|
*/
|
|
97
97
|
interceptor?: <T>(data: T, dataType: string) => T | null | undefined;
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
/**
|
|
100
100
|
* Callback before cloning.
|
|
101
101
|
*/
|
|
102
|
-
onBeforeClone?: (
|
|
102
|
+
onBeforeClone?: (result: BeforeCloneResult) => void;
|
|
103
103
|
|
|
104
104
|
/**
|
|
105
105
|
* Callback after cloning.
|
|
106
106
|
* @param result Object containing cloning result.
|
|
107
107
|
*/
|
|
108
108
|
onAfterClone?: (result: AfterCloneResult) => void;
|
|
109
|
+
|
|
110
|
+
//深度复制时的临时保存的父对象
|
|
111
|
+
parent?: Record<string | symbol, any> | Map<any, any> | Set<any> | any[] | null;
|
|
112
|
+
}
|
|
113
|
+
export interface BeforeCloneResult {
|
|
114
|
+
input: any;
|
|
115
|
+
type: string;
|
|
116
|
+
parent?: Record<string | symbol, any> | Map<any, any> | Set<any> | any[] | null;
|
|
109
117
|
}
|
|
110
118
|
export interface AfterCloneResult<T = any> {
|
|
111
119
|
// Cloned data
|
|
@@ -116,6 +124,7 @@ export interface AfterCloneResult<T = any> {
|
|
|
116
124
|
type: string;
|
|
117
125
|
// Whether cloning was performed
|
|
118
126
|
cloned: boolean;
|
|
127
|
+
parent?: Record<string | symbol, any> | Map<any, any> | Set<any> | any[] | null;
|
|
119
128
|
}
|
|
120
129
|
//支持原始值的复制,包括Number、String、Boolean、Null
|
|
121
130
|
//支持Date和Regex对象值复制(值转换)
|
|
@@ -146,6 +155,7 @@ const deepClone = <T>(data: T, options: DeepCloneOptions = {}): T => {
|
|
|
146
155
|
input: data,
|
|
147
156
|
type: dataType,
|
|
148
157
|
cloned: result !== data,
|
|
158
|
+
parent: opts.parent
|
|
149
159
|
});
|
|
150
160
|
return result as T;
|
|
151
161
|
}
|
|
@@ -153,41 +163,52 @@ const deepClone = <T>(data: T, options: DeepCloneOptions = {}): T => {
|
|
|
153
163
|
}
|
|
154
164
|
|
|
155
165
|
// Callback before cloning
|
|
156
|
-
opts.onBeforeClone?.(
|
|
166
|
+
opts.onBeforeClone?.({
|
|
167
|
+
input: data,
|
|
168
|
+
type: dataType,
|
|
169
|
+
parent: opts.parent
|
|
170
|
+
});
|
|
157
171
|
|
|
158
|
-
let newData,
|
|
172
|
+
let newData: any,
|
|
159
173
|
cloned = true;
|
|
160
174
|
|
|
161
175
|
if (dataType === 'Object' && opts.cloneObject) {
|
|
162
176
|
const newObj: Record<string | symbol, any> = {},
|
|
163
177
|
symbols = Object.getOwnPropertySymbols(data);
|
|
164
178
|
|
|
179
|
+
//存储parent对象,在下一次深复制时使用
|
|
180
|
+
opts.parent = data as any;
|
|
181
|
+
|
|
165
182
|
// Clone regular properties
|
|
166
183
|
for (const key in data) {
|
|
167
|
-
|
|
184
|
+
//临时保存父对象
|
|
185
|
+
newObj[key] = deepClone((data as any)[key], opts);
|
|
168
186
|
}
|
|
169
187
|
|
|
170
188
|
// Clone Symbol properties
|
|
171
189
|
if (symbols.length > 0) {
|
|
172
190
|
for (const symbol of symbols) {
|
|
173
|
-
newObj[symbol] = deepClone((data as any)[symbol],opts);
|
|
191
|
+
newObj[symbol] = deepClone((data as any)[symbol], opts);
|
|
174
192
|
}
|
|
175
193
|
}
|
|
176
194
|
newData = newObj as T;
|
|
177
195
|
} else if (dataType === 'Array' && opts.cloneArray) {
|
|
178
|
-
|
|
196
|
+
opts.parent = data as any;
|
|
197
|
+
newData = (data as any[]).map(item => deepClone(item, opts)) as T;
|
|
179
198
|
} else if (dataType === 'Map' && opts.cloneMap) {
|
|
180
199
|
const newMap = new Map();
|
|
200
|
+
opts.parent = data as any;
|
|
181
201
|
for (const [key, value] of data as Map<any, any>) {
|
|
182
202
|
// Both Map keys and values need deep cloning
|
|
183
|
-
newMap.set(deepClone(key,opts), deepClone(value,opts));
|
|
203
|
+
newMap.set(deepClone(key, opts), deepClone(value, opts));
|
|
184
204
|
}
|
|
185
205
|
newData = newMap as T;
|
|
186
206
|
} else if (dataType === 'Set' && opts.cloneSet) {
|
|
187
207
|
const newSet = new Set();
|
|
208
|
+
opts.parent = data as any;
|
|
188
209
|
for (const value of data as Set<any>) {
|
|
189
210
|
// Set values need deep cloning
|
|
190
|
-
newSet.add(deepClone(value,opts));
|
|
211
|
+
newSet.add(deepClone(value, opts));
|
|
191
212
|
}
|
|
192
213
|
newData = newSet as T;
|
|
193
214
|
} else if (dataType === 'Date' && opts.cloneDate) {
|
|
@@ -195,11 +216,11 @@ const deepClone = <T>(data: T, options: DeepCloneOptions = {}): T => {
|
|
|
195
216
|
} else if (dataType === 'RegExp' && opts.cloneRegex) {
|
|
196
217
|
const regex = data as RegExp;
|
|
197
218
|
newData = new RegExp(regex.source, regex.flags) as T;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
219
|
+
// } else if ((dataType.includes('HTML') && opts.cloneElement) ||
|
|
220
|
+
// (dataType === 'DocumentFragment' && opts.cloneFragment)
|
|
221
|
+
//) {
|
|
201
222
|
//Text,Comment,HTML*Element,DocumentFragment,Attr
|
|
202
|
-
|
|
223
|
+
// newData = (data as any).cloneNode(true) as T;
|
|
203
224
|
} else {
|
|
204
225
|
// Number, String, Boolean, Symbol, Function,Error,Promise,ArrayBuffer,Blob,File, return directly
|
|
205
226
|
newData = data;
|
|
@@ -211,6 +232,7 @@ const deepClone = <T>(data: T, options: DeepCloneOptions = {}): T => {
|
|
|
211
232
|
input: data,
|
|
212
233
|
type: dataType,
|
|
213
234
|
cloned,
|
|
235
|
+
parent: opts.parent
|
|
214
236
|
});
|
|
215
237
|
return newData;
|
|
216
238
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/16 09:00:41
|
|
3
|
+
* @function getDataType
|
|
4
|
+
* @description Get object type.Can detect object types such as Array, Object, Function,
|
|
5
|
+
* Window,Location,History,Navigator,XMLHttpRequest, WebSocket,FileReader,MediaStream
|
|
6
|
+
* Class , String, Number, Boolean, Date, Symbol ,File ,Blob,
|
|
7
|
+
* Error,Promise,ArrayBuffer,TypedArray, Set, weakSet, Map, weakMap, Null, Undefined,
|
|
8
|
+
* Text, DocumentFragment,Comment, XMLDocument, ProcessingInstruction, Range, TreeWalker,
|
|
9
|
+
* NodeIterator,SVGSVGElement,MathMLElement, HTMLxxxElement (Dom nodes all contain HTML),Promise,AsyncFunction and Instance.
|
|
10
|
+
* @param {*} obj - Can be any object
|
|
11
|
+
* @returns {string} - Returns the name of the data type.
|
|
12
|
+
*/
|
|
13
|
+
'use strict';
|
|
14
|
+
const getDataType = (obj) => {
|
|
15
|
+
let tmp = Object.prototype.toString.call(obj).slice(8, -1), result;
|
|
16
|
+
if (tmp === 'Function' && /^\s*class\s+/.test(obj.toString())) {
|
|
17
|
+
result = 'Class';
|
|
18
|
+
}
|
|
19
|
+
else if (tmp === 'Object' && Object.getPrototypeOf(obj) !== Object.prototype) {
|
|
20
|
+
result = 'Instance';
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
result = tmp;
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
//document.createElement -> HTMLxxxElement
|
|
27
|
+
//document.createDocumentFragment() -> DocumentFragment
|
|
28
|
+
//document.createComment() -> Comment
|
|
29
|
+
//document.createTextNode -> Text
|
|
30
|
+
//document.createCDATASection() -> XMLDocument
|
|
31
|
+
//document.createProcessingInstruction() -> ProcessingInstruction
|
|
32
|
+
//document.createRange() -> Range
|
|
33
|
+
//document.createTreeWalker() -> TreeWalker
|
|
34
|
+
//document.createNodeIterator() -> NodeIterator
|
|
35
|
+
//document.createElementNS('http://www.w3.org/2000/svg', 'svg'); -> SVGSVGElement
|
|
36
|
+
//document.createElementNS('http://www.w3.org/1998/Math/MathML', 'math'); -> MathMLElement
|
|
37
|
+
};
|
|
38
|
+
export default getDataType;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 14:22:26
|
|
3
|
+
* @function isEmpty
|
|
4
|
+
* @description Determine whether it is empty data.The data itself is empty data: 0| ''|false|undefined|null; <br>empty function: function () {}|() => {}; <br>empty array and empty objects: []|{}| [null]| [ undefined]| ['']| [""];<br> empty symbol object: symbol()|symbol.For(), will be judged as empty.
|
|
5
|
+
* @param {*} data - Can be any data
|
|
6
|
+
* @returns {boolean} - Return true or false
|
|
7
|
+
* @example
|
|
8
|
+
* ax.isEmpty([null]);
|
|
9
|
+
* <!--return true-->
|
|
10
|
+
*/
|
|
11
|
+
//简介:判断是否为空数据。本身为空的数据:0|''|false|undefined|null;空函数:function(){}|()=>{};空数组和空对象:[]|{}|[null]|[undefined]|['']|[""];空Symbol对象:Symbol()|Symbol.for(),都将判断为空。
|
|
12
|
+
//返回:true或false
|
|
13
|
+
'use strict';
|
|
14
|
+
import getDataType from './getDataType';
|
|
15
|
+
const isEmpty = (data) => {
|
|
16
|
+
let type = getDataType(data), flag;
|
|
17
|
+
if (!data) {
|
|
18
|
+
//0,'',false,undefined,null
|
|
19
|
+
flag = true;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
//function(){}|()=>{}
|
|
23
|
+
//[null]|[undefined]|['']|[""]
|
|
24
|
+
//[]|{}
|
|
25
|
+
//Symbol()|Symbol.for()
|
|
26
|
+
//Set,Map
|
|
27
|
+
//Date/Regex
|
|
28
|
+
flag = (type === 'Object') ? (Object.keys(data).length === 0) :
|
|
29
|
+
(type === 'Array') ? data.join('') === '' :
|
|
30
|
+
(type === 'Function') ? (data.toString().replace(/\s+/g, '').match(/{.*}/g)[0] === '{}') :
|
|
31
|
+
(type === 'Symbol') ? (data.toString().replace(/\s+/g, '').match(/\(.*\)/g)[0] === '()') :
|
|
32
|
+
(type === 'Set' || type === 'Map') ? data.size === 0 :
|
|
33
|
+
type === 'Date' ? isNaN(data.getTime()) :
|
|
34
|
+
type === 'RegExp' ? data.source === '' :
|
|
35
|
+
type === 'ArrayBuffer' ? data.byteLength === 0 :
|
|
36
|
+
(type === 'NodeList' || type === 'HTMLCollection') ? data.length === 0 :
|
|
37
|
+
('length' in data && typeof data.length === 'number') ? data.length === 0 :
|
|
38
|
+
('size' in data && typeof data.size === 'number') ? data.size === 0 :
|
|
39
|
+
(type === 'Error' || data instanceof Error) ? data.message === '' :
|
|
40
|
+
(type.includes('Array') && (['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array'].includes(type))) ? data.length === 0 :
|
|
41
|
+
false;
|
|
42
|
+
}
|
|
43
|
+
return flag;
|
|
44
|
+
};
|
|
45
|
+
export default isEmpty;
|
package/src/isEmpty.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 14:22:26
|
|
3
|
+
* @function isEmpty
|
|
4
|
+
* @description Determine whether it is empty data.The data itself is empty data: 0| ''|false|undefined|null; <br>empty function: function () {}|() => {}; <br>empty array and empty objects: []|{}| [null]| [ undefined]| ['']| [""];<br> empty symbol object: symbol()|symbol.For(), will be judged as empty.
|
|
5
|
+
* @param {*} data - Can be any data
|
|
6
|
+
* @returns {boolean} - Return true or false
|
|
7
|
+
* @example
|
|
8
|
+
* ax.isEmpty([null]);
|
|
9
|
+
* <!--return true-->
|
|
10
|
+
*/
|
|
11
|
+
//简介:判断是否为空数据。本身为空的数据:0|''|false|undefined|null;空函数:function(){}|()=>{};空数组和空对象:[]|{}|[null]|[undefined]|['']|[""];空Symbol对象:Symbol()|Symbol.for(),都将判断为空。
|
|
12
|
+
//返回:true或false
|
|
13
|
+
'use strict';
|
|
14
|
+
import getDataType from './getDataType';
|
|
15
|
+
const isEmpty = (data) => {
|
|
16
|
+
let type = getDataType(data), flag;
|
|
17
|
+
if (!data) {
|
|
18
|
+
//0,'',false,undefined,null
|
|
19
|
+
flag = true;
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
//function(){}|()=>{}
|
|
23
|
+
//[null]|[undefined]|['']|[""]
|
|
24
|
+
//[]|{}
|
|
25
|
+
//Symbol()|Symbol.for()
|
|
26
|
+
//Set,Map
|
|
27
|
+
//Date/Regex
|
|
28
|
+
flag = (type === 'Object') ? (Object.keys(data).length === 0) :
|
|
29
|
+
(type === 'Array') ? data.join('') === '' :
|
|
30
|
+
(type === 'Function') ? (data.toString().replace(/\s+/g, '').match(/{.*}/g)[0] === '{}') :
|
|
31
|
+
(type === 'Symbol') ? (data.toString().replace(/\s+/g, '').match(/\(.*\)/g)[0] === '()') :
|
|
32
|
+
(type === 'Set' || type === 'Map') ? data.size === 0 :
|
|
33
|
+
type === 'Date' ? isNaN(data.getTime()) :
|
|
34
|
+
type === 'RegExp' ? data.source === '' :
|
|
35
|
+
type === 'ArrayBuffer' ? data.byteLength === 0 :
|
|
36
|
+
(type === 'NodeList' || type === 'HTMLCollection') ? data.length === 0 :
|
|
37
|
+
('length' in data && typeof data.length === 'number') ? data.length === 0 :
|
|
38
|
+
('size' in data && typeof data.size === 'number') ? data.size === 0 :
|
|
39
|
+
(type === 'Error' || data instanceof Error) ? data.message === '' :
|
|
40
|
+
(type.includes('Array') && (['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array'].includes(type))) ? data.length === 0 :
|
|
41
|
+
false;
|
|
42
|
+
}
|
|
43
|
+
return flag;
|
|
44
|
+
};
|
|
45
|
+
export default isEmpty;
|
package/src/isEmpty.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/25 14:22:26
|
|
3
|
+
* @function isEmpty
|
|
4
|
+
* @description Determine whether it is empty data.The data itself is empty data: 0| ''|false|undefined|null; <br>empty function: function () {}|() => {}; <br>empty array and empty objects: []|{}| [null]| [ undefined]| ['']| [""];<br> empty symbol object: symbol()|symbol.For(), will be judged as empty.
|
|
5
|
+
* @param {*} data - Can be any data
|
|
6
|
+
* @returns {boolean} - Return true or false
|
|
7
|
+
* @example
|
|
8
|
+
* ax.isEmpty([null]);
|
|
9
|
+
* <!--return true-->
|
|
10
|
+
*/
|
|
11
|
+
//简介:判断是否为空数据。本身为空的数据:0|''|false|undefined|null;空函数:function(){}|()=>{};空数组和空对象:[]|{}|[null]|[undefined]|['']|[""];空Symbol对象:Symbol()|Symbol.for(),都将判断为空。
|
|
12
|
+
//返回:true或false
|
|
13
|
+
'use strict';
|
|
14
|
+
import getDataType from './getDataType';
|
|
15
|
+
const isEmpty = (data: any): boolean => {
|
|
16
|
+
let type = getDataType(data), flag: boolean;
|
|
17
|
+
if (!data) {
|
|
18
|
+
//0,'',false,undefined,null
|
|
19
|
+
flag = true;
|
|
20
|
+
} else {
|
|
21
|
+
//function(){}|()=>{}
|
|
22
|
+
//[null]|[undefined]|['']|[""]
|
|
23
|
+
//[]|{}
|
|
24
|
+
//Symbol()|Symbol.for()
|
|
25
|
+
//Set,Map
|
|
26
|
+
//Date/Regex
|
|
27
|
+
flag = (type === 'Object') ? (Object.keys(data).length === 0) :
|
|
28
|
+
(type === 'Array') ? data.join('') === '' :
|
|
29
|
+
(type === 'Function') ? (data.toString().replace(/\s+/g, '').match(/{.*}/g)[0] === '{}') :
|
|
30
|
+
(type === 'Symbol') ? (data.toString().replace(/\s+/g, '').match(/\(.*\)/g)[0] === '()') :
|
|
31
|
+
(type === 'Set' || type === 'Map') ? data.size === 0 :
|
|
32
|
+
type === 'Date' ? isNaN(data.getTime()) :
|
|
33
|
+
type === 'RegExp' ? data.source === '' :
|
|
34
|
+
type === 'ArrayBuffer' ? data.byteLength === 0 :
|
|
35
|
+
(type === 'NodeList' || type === 'HTMLCollection') ? data.length === 0 :
|
|
36
|
+
('length' in data && typeof data.length === 'number') ? data.length === 0 :
|
|
37
|
+
('size' in data && typeof data.size === 'number') ? data.size === 0 :
|
|
38
|
+
(type === 'Error' || data instanceof Error) ? data.message === '' :
|
|
39
|
+
(type.includes('Array') && (['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array', 'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array'].includes(type))) ? data.length === 0 :
|
|
40
|
+
false;
|
|
41
|
+
}
|
|
42
|
+
return flag;
|
|
43
|
+
}
|
|
44
|
+
export default isEmpty;
|
package/src/shallowCopy.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since Last modified: 2025/12/25
|
|
2
|
+
* @since Last modified: 2025/12/25 14:29:53
|
|
3
3
|
* shallowCopy
|
|
4
4
|
*
|
|
5
5
|
* This function performs a shallow copy of various data structures:
|
|
@@ -7,13 +7,21 @@
|
|
|
7
7
|
* - Map
|
|
8
8
|
* - Array
|
|
9
9
|
* - Plain Object (including properties with Symbol keys)
|
|
10
|
+
* - Date
|
|
11
|
+
* - RegExp
|
|
12
|
+
* - Buffer (Node.js)
|
|
13
|
+
* - ArrayBuffer and Typed Arrays
|
|
14
|
+
* - WeakSet
|
|
15
|
+
* - WeakMap
|
|
16
|
+
* - Error
|
|
10
17
|
*
|
|
11
18
|
* It returns a new instance of the data structure, but the elements or properties of reference types (such as objects or arrays) will be copied by reference.
|
|
12
19
|
* Primitive types (e.g., number, string, boolean) will be returned directly.
|
|
13
20
|
*/
|
|
14
21
|
'use strict';
|
|
22
|
+
import copyObjectWithSymbol from "./copyObjectWithSymbol";
|
|
15
23
|
import getDataType from "./getDataType";
|
|
16
|
-
const shallowCopy = (data) => {
|
|
24
|
+
const shallowCopy = (data, options = {}) => {
|
|
17
25
|
const dataType = getDataType(data);
|
|
18
26
|
// Check if data is a Set
|
|
19
27
|
if (dataType === 'Set') {
|
|
@@ -32,13 +40,37 @@ const shallowCopy = (data) => {
|
|
|
32
40
|
}
|
|
33
41
|
// Check if data is a Plain Object (including Symbol keys)
|
|
34
42
|
if (dataType === 'object') {
|
|
35
|
-
|
|
36
|
-
const symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc, sym) => {
|
|
37
|
-
acc[sym] = obj[sym];
|
|
38
|
-
return acc;
|
|
39
|
-
}, {});
|
|
43
|
+
// Ensure the object type includes string and symbol keys
|
|
40
44
|
// Shallow copy the object and include the Symbol properties
|
|
41
|
-
return
|
|
45
|
+
return copyObjectWithSymbol(data);
|
|
46
|
+
}
|
|
47
|
+
// Check if data is a Date
|
|
48
|
+
if (dataType === 'Date') {
|
|
49
|
+
return new Date(data.getTime());
|
|
50
|
+
}
|
|
51
|
+
// Check if data is a RegExp
|
|
52
|
+
if (dataType === 'RegExp') {
|
|
53
|
+
return new RegExp(data.source, data.flags);
|
|
54
|
+
}
|
|
55
|
+
// Check if data is a Buffer (for Node.js)
|
|
56
|
+
if (dataType === 'Buffer') {
|
|
57
|
+
return Buffer.from(data);
|
|
58
|
+
}
|
|
59
|
+
// Check if data is an ArrayBuffer or TypedArray
|
|
60
|
+
if (dataType === 'ArrayBuffer' || ArrayBuffer.isView(data)) {
|
|
61
|
+
return data.slice(0);
|
|
62
|
+
}
|
|
63
|
+
// Check if data is a WeakSet
|
|
64
|
+
if (dataType === 'WeakSet') {
|
|
65
|
+
return new WeakSet([...data]);
|
|
66
|
+
}
|
|
67
|
+
// Check if data is a WeakMap
|
|
68
|
+
if (dataType === 'WeakMap') {
|
|
69
|
+
return new WeakMap([...data]);
|
|
70
|
+
}
|
|
71
|
+
// Check if data is an Error
|
|
72
|
+
if (dataType === 'Error') {
|
|
73
|
+
return new Error(data.message);
|
|
42
74
|
}
|
|
43
75
|
// For other types (such as numbers, strings, booleans, etc.), return the original value
|
|
44
76
|
return data;
|
package/src/shallowCopy.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @since Last modified: 2025/12/25
|
|
2
|
+
* @since Last modified: 2025/12/25 14:29:53
|
|
3
3
|
* shallowCopy
|
|
4
4
|
*
|
|
5
5
|
* This function performs a shallow copy of various data structures:
|
|
@@ -7,15 +7,23 @@
|
|
|
7
7
|
* - Map
|
|
8
8
|
* - Array
|
|
9
9
|
* - Plain Object (including properties with Symbol keys)
|
|
10
|
+
* - Date
|
|
11
|
+
* - RegExp
|
|
12
|
+
* - Buffer (Node.js)
|
|
13
|
+
* - ArrayBuffer and Typed Arrays
|
|
14
|
+
* - WeakSet
|
|
15
|
+
* - WeakMap
|
|
16
|
+
* - Error
|
|
10
17
|
*
|
|
11
18
|
* It returns a new instance of the data structure, but the elements or properties of reference types (such as objects or arrays) will be copied by reference.
|
|
12
19
|
* Primitive types (e.g., number, string, boolean) will be returned directly.
|
|
13
20
|
*/
|
|
14
21
|
'use strict';
|
|
15
22
|
|
|
23
|
+
import copyObjectWithSymbol from "./copyObjectWithSymbol";
|
|
16
24
|
import getDataType from "./getDataType";
|
|
17
25
|
|
|
18
|
-
const shallowCopy = (data: any): any => {
|
|
26
|
+
const shallowCopy = (data: any,options={}): any => {
|
|
19
27
|
const dataType = getDataType(data);
|
|
20
28
|
|
|
21
29
|
// Check if data is a Set
|
|
@@ -38,14 +46,44 @@ const shallowCopy = (data: any): any => {
|
|
|
38
46
|
|
|
39
47
|
// Check if data is a Plain Object (including Symbol keys)
|
|
40
48
|
if (dataType === 'object') {
|
|
41
|
-
|
|
42
|
-
const symbolProperties = Object.getOwnPropertySymbols(obj).reduce((acc: { [key: symbol]: any }, sym: symbol) => {
|
|
43
|
-
acc[sym] = obj[sym];
|
|
44
|
-
return acc;
|
|
45
|
-
}, {});
|
|
46
|
-
|
|
49
|
+
// Ensure the object type includes string and symbol keys
|
|
47
50
|
// Shallow copy the object and include the Symbol properties
|
|
48
|
-
return
|
|
51
|
+
return copyObjectWithSymbol(data);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Check if data is a Date
|
|
55
|
+
if (dataType === 'Date') {
|
|
56
|
+
return new Date(data.getTime());
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Check if data is a RegExp
|
|
60
|
+
if (dataType === 'RegExp') {
|
|
61
|
+
return new RegExp(data.source, data.flags);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Check if data is a Buffer (for Node.js)
|
|
65
|
+
if (dataType === 'Buffer') {
|
|
66
|
+
return Buffer.from(data);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check if data is an ArrayBuffer or TypedArray
|
|
70
|
+
if (dataType === 'ArrayBuffer' || ArrayBuffer.isView(data)) {
|
|
71
|
+
return data.slice(0);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Check if data is a WeakSet
|
|
75
|
+
if (dataType === 'WeakSet') {
|
|
76
|
+
return new WeakSet([...data]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check if data is a WeakMap
|
|
80
|
+
if (dataType === 'WeakMap') {
|
|
81
|
+
return new WeakMap([...data]);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Check if data is an Error
|
|
85
|
+
if (dataType === 'Error') {
|
|
86
|
+
return new Error(data.message);
|
|
49
87
|
}
|
|
50
88
|
|
|
51
89
|
// For other types (such as numbers, strings, booleans, etc.), return the original value
|