实现思路
- 基本数据类型判断:使用
typeof
操作符判断基础数据类型,如 string
、number
、boolean
、undefined
、symbol
、bigint
。
- 引用数据类型判断:
- 数组:使用
Array.isArray
方法判断是否为数组。
- 普通对象:使用
Object.prototype.toString.call
方法来准确判断对象类型,对于React、Vue等框架的实例对象,也能通过此方法识别出其构造函数信息。例如,React组件实例可能会有类似 [object Object]
中包含React相关标识,Vue实例同理。
- 函数:使用
typeof
判断为 function
来确定。
- 第三方库特殊数据类型:有些第三方库可能提供了判断其特殊数据类型的方法,优先使用这些官方提供的方法。如果没有,可以通过查看其文档,了解其构造函数等特征,使用
Object.prototype.toString.call
结合这些特征来判断。
- 优化策略:
- 缓存判断结果:对于频繁判断的数据类型,可以使用缓存机制。例如,创建一个Map对象,将已判断过的数据及其类型存储起来,下次判断时先检查缓存。
- 减少操作:在判断过程中,尽量减少不必要的计算和操作。例如,对于已经确定类型的数据,不再重复判断。
- 异步处理:对于大规模数据,可以考虑异步处理,将数据分成小块进行判断,避免阻塞主线程。在浏览器环境下,可以使用
requestIdleCallback
或 setTimeout
来实现异步处理。
- 兼容性处理:在不同浏览器环境下,要注意
Object.prototype.toString.call
等方法的兼容性。可以使用一些兼容性库,如 core - js
来确保代码在各种浏览器中都能正常运行。
关键代码示例
// 缓存对象
const typeCache = new Map();
function getType(obj) {
if (typeCache.has(obj)) {
return typeCache.get(obj);
}
let type;
if (typeof obj === 'object') {
if (Array.isArray(obj)) {
type = 'array';
} else {
type = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
} else {
type = typeof obj;
}
typeCache.set(obj, type);
return type;
}
// 示例使用
const reactInstance = { /* React实例对象 */ };
const vueInstance = { /* Vue实例对象 */ };
const normalObj = { key: 'value' };
const arr = [1, 2, 3];
const num = 10;
console.log(getType(reactInstance));
console.log(getType(vueInstance));
console.log(getType(normalObj));
console.log(getType(arr));
console.log(getType(num));
异步处理示例(使用setTimeout模拟)
function asyncGetType(dataList) {
return new Promise((resolve) => {
const results = [];
function processNext() {
const obj = dataList.shift();
if (obj) {
const type = getType(obj);
results.push(type);
setTimeout(processNext, 0);
} else {
resolve(results);
}
}
setTimeout(processNext, 0);
});
}
// 示例使用
const largeData = Array.from({ length: 1000 }, (_, i) => ({ value: i }));
asyncGetType(largeData).then((types) => {
console.log(types);
});