JavaScript中准确判断数据类型有多种方法,每种都有其适用场景和局限性。以下是5种主要方法的深度对比:
typeof 操作符typeof "hello" // "string"
typeof 42 // "number"
typeof true // "boolean"
typeof undefined // "undefined"
typeof function(){} // "function"
typeof null // "object" (历史遗留问题)
typeof [] // "object"
typeof {} // "object"
typeof new Date() // "object"
特点:
instanceof 操作符[] instanceof Array // true
new Date() instanceof Date // true
{} instanceof Object // true
[] instanceof Object // true (原型链上)
"hello" instanceof String // false (字面量)
new String("hello") instanceof String // true
特点:
Object.prototype.toString.call()Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(new Date()) // "[object Date]"
Object.prototype.toString.call(function(){}) // "[object Function]"
特点:
Symbol.toStringTagconstructor 属性[].constructor === Array // true
"".constructor === String // true
(123).constructor === Number // true
new Date().constructor === Date // true
特点:
Array.isArray()(数组专用)Array.isArray([]) // true
Array.isArray({}) // false
Array.isArray("") // false
特点:
| 方法 | 优点 | 缺点 | 推荐场景 |
|---|---|---|---|
typeof |
简单快速,适合基础类型 | 无法区分对象类型,null判断错误 | 基本类型检查,undefined检测 |
instanceof |
检查原型链,适合类实例判断 | 不适用于字面量,跨iframe失效 | 自定义类实例检查 |
toString.call() |
最全面准确,支持所有类型 | 语法稍复杂 | 通用、高精度类型判断 |
constructor |
直接访问构造函数 | 可被修改,不安全 | 信任环境中的类型判断 |
Array.isArray() |
数组检测最可靠 | 只能用于数组 | 专用于数组验证 |
function getType(value) {
return Object.prototype.toString.call(value)
.slice(8, -1)
.toLowerCase();
}
// 使用示例
getType([]) // "array"
getType(null) // "null"
getType(new Date()) // "date"
const TypeChecker = {
isString: v => typeof v === 'string',
isNumber: v => typeof v === 'number' && !isNaN(v),
isBoolean: v => typeof v === 'boolean',
isUndefined: v => v === undefined,
isNull: v => v === null,
isArray: v => Array.isArray(v),
isObject: v => v !== null && typeof v === 'object' && !Array.isArray(v),
isFunction: v => typeof v === 'function',
isDate: v => Object.prototype.toString.call(v) === '[object Date]',
isRegExp: v => Object.prototype.toString.call(v) === '[object RegExp]',
isPromise: v => v && typeof v.then === 'function',
isEmptyObject: v => TypeChecker.isObject(v) && Object.keys(v).length === 0,
isNil: v => v == null // null 或 undefined
};
Object.prototype.toString.call()最可靠Array.isArray()typeof + 特殊处理nullinstanceof(注意限制)typeof或专门优化的检查typeof NaN === 'number',需要额外用isNaN()或Number.isNaN()
async函数:typeof asyncFunc === 'function'
箭头函数:同样返回"function"
Symbol类型:typeof Symbol() === 'symbol'
BigInt:typeof 123n === 'bigint'
选择哪种方法取决于具体需求:如果只需要基础类型判断,typeof足够;如果需要精确的类型信息,推荐使用Object.prototype.toString.call()。