JavaScript 数据类型检测的 9 种方法与使用优先级

一、方法总结
  1. typeof

    • 语法:typeof variable
    • 返回值:基本类型字符串(如 "number""string"
    • 局限:无法区分 null(返回 "object")、数组(返回 "object"
    • 优先级:⭐️⭐️⭐️⭐️(基础类型首选)
  2. Object.prototype.toString.call()

    • 语法:Object.prototype.toString.call(value)
    • 返回值:[object Type](如 [object Array]
    • 特点:最精确的内置对象检测
    • 优先级:⭐️⭐️⭐️⭐️⭐️(对象类型首选)
  3. instanceof

    • 语法:value instanceof Constructor
    • 原理:检查原型链是否包含构造函数
    • 局限:跨 iframe 失效,基本类型无效
    • 优先级:⭐️⭐️⭐️(自定义对象检测)
  4. Array.isArray()

    • 语法:Array.isArray(value)
    • 返回值:布尔值(仅检测数组)
    • 替代方案:Object.prototype.toString.call(value) === "[object Array]"
    • 优先级:⭐️⭐️⭐️⭐️⭐️(数组专用最优解)
  5. Number.isNaN()

    • 语法:Number.isNaN(value)
    • 特点:严格检测 NaN(区别于全局 isNaN
    • 示例:Number.isNaN(NaN) === true
    • 优先级:⭐️⭐️⭐️⭐️(NaN 检测唯一可靠方法)
  6. constructor 属性

    • 语法:value.constructor === Type
    • 风险:属性可被修改(如 obj.constructor = Object
    • 优先级:⭐️(不推荐,易出错)
  7. === null=== undefined

    • 语法:value === nullvalue === undefined
    • 说明:直接比较特殊值
    • 优先级:⭐️⭐️⭐️⭐️(null/undefined 检测最简方式)
  8. isFinite()

    • 语法:Number.isFinite(value)
    • 作用:检测有限数字(排除 Infinity/NaN
    • 注意:全局 isFinite 会强制类型转换
    • 优先级:⭐️⭐️(数字校验场景)
  9. 鸭子类型(Duck Typing)

    • 原理:检查属性/方法存在性(如 "length" in value
    • 示例:typeof value.then === "function" 检测 Promise
    • 优先级:⭐️⭐️(动态类型场景备用方案)

二、使用优先级排序
场景 推荐方法 优先级 原因
基本类型 typeof 快速区分 string/number/boolean
null/undefined === null=== undefined 直接准确
数组 Array.isArray() 最高 专为数组设计,无兼容问题
内置对象 Object.prototype.toString.call() 最高 返回精确类型标签(如 Date/RegExp
NaN Number.isNaN() 避免全局 isNaN 的类型转换问题
自定义对象 instanceof 依赖原型链,跨环境失效时需谨慎
数字范围 Number.isFinite() 特定场景替代 typeof
动态类型 鸭子类型 灵活性高,但需预知接口
构造函数依赖 constructor 不推荐 属性易被篡改

三、最佳实践总结
  1. 基础类型检测:优先使用 typeof + 直接比较(null/undefined)。
  2. 对象类型检测
    • 数组 → Array.isArray()
    • 其他内置对象 → Object.prototype.toString.call()
  3. 特殊值处理
    • NaNNumber.isNaN()
    • 数字范围 → Number.isFinite()
  4. 避免方法
    • constructor(不可靠)
    • 全局 isNaN(会转换类型)
  5. 复合类型:组合使用(如先用 typeof 筛基本类型,再用 toString 检测对象)。

示例代码:

// 精确检测数组 + 日期对象
const checkType = (value) => {
  if (Array.isArray(value)) return "Array";
  return Object.prototype.toString.call(value).slice(8, -1);
};
console.log(checkType([])); // "Array"
console.log(checkType(new Date())); // "Date"

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐