兴化市文章资讯

JavaScript准确判断数据类型的5 种方法深度对比

2026-04-13 11:41:02 浏览次数:0
详细信息

JavaScript中准确判断数据类型有多种方法,每种都有其适用场景和局限性。以下是5种主要方法的深度对比:

1. 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"

特点:

2. 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

特点:

3. 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]"

特点:

4. constructor 属性

[].constructor === Array           // true
"".constructor === String         // true
(123).constructor === Number      // true
new Date().constructor === Date   // true

特点:

5. Array.isArray()(数组专用)

Array.isArray([])      // true
Array.isArray({})      // false
Array.isArray("")      // false

特点:

深度对比表

方法 优点 缺点 推荐场景
typeof 简单快速,适合基础类型 无法区分对象类型,null判断错误 基本类型检查,undefined检测
instanceof 检查原型链,适合类实例判断 不适用于字面量,跨iframe失效 自定义类实例检查
toString.call() 最全面准确,支持所有类型 语法稍复杂 通用、高精度类型判断
constructor 直接访问构造函数 可被修改,不安全 信任环境中的类型判断
Array.isArray() 数组检测最可靠 只能用于数组 专用于数组验证

最佳实践推荐

1. 通用类型判断函数

function getType(value) {
  return Object.prototype.toString.call(value)
    .slice(8, -1)
    .toLowerCase();
}

// 使用示例
getType([])        // "array"
getType(null)      // "null"
getType(new Date()) // "date"

2. 类型判断工具函数

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
};

3. 实际应用建议

特殊注意事项

NaN判断typeof NaN === 'number',需要额外用isNaN()Number.isNaN() async函数typeof asyncFunc === 'function' 箭头函数:同样返回"function" Symbol类型typeof Symbol() === 'symbol' BigInttypeof 123n === 'bigint'

选择哪种方法取决于具体需求:如果只需要基础类型判断,typeof足够;如果需要精确的类型信息,推荐使用Object.prototype.toString.call()

相关推荐