javascript数据类型_如何检测变量类型

typeof能准确判断string、number、boolean、undefined、function、symbol和bigint,但对所有对象(含数组、日期、正则、null等)均返回"object",无法区分具体引用类型。

typeof 能判断什么,不能判断什么

typeof 是最常用的类型检测操作符,但它对引用类型的支持很有限。它能准确区分 stringnumberbooleanundefinedfunctionsymbol,但对所有对象(包括数组、正则、日期、null)都返回 "object"

特别注意:typeof null === "object" 是历史遗留 bug,至今未修复。

  • typeof []"object"
  • typeof null"object"
  • typeof new Date()"object"
  • typeof /abc/"object"
  • typeof Promise.resolve()"object"

Object.prototype.toString.call() 是更可靠的检测方式

每个内置类型的构造函数都有对应的内部 [[Class]] 标签,Object.prototype.toString.call() 可以读取这个标签,返回形如 "[object Array]" 的字符串。这是目前最通用、最标准的类型检测方法。

Object.prototype.toString.call([])        // "[object Array]"
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(/abc/)     // "[object RegExp]"
Object.prototype.toString.call(BigInt(1)) // "[object BigInt]"
Object.prototype.toString.call(1n)        // "[object BigInt]"

实际使用时建议封装成工具函数:

function typeOf(val) {
  return Object.prototype.toString.call(val).slice(8, -1).toLowerCase();
}
typeOf([1, 2])   // "array"
typeOf(null)     // "null"
typeOf(new Set())// "set"

Array.isArray() 和 instanceof 的适用边界

Array.isArray() 是检测数组的首选,比 toString 更语义化、性能略优,且在跨 iframe 场景下仍可靠(instanceof Array 在跨环境时会失效)。

instanceof 适用于你明确知道构造函数来源、且不涉及多全局环境(比如多个 iframe 或 Web Worker)的场景。它依赖原型链,对原始值无效,也不能识别基础类型。

  • Array.isArray([])true(推荐)
  • [] instanceof Arraytrue(同源下可用)
  • {} instanceof Objecttrue,但 new String('a') instanceof Object 也返回 true,容易误判包装对象
  • "" instanceof Stringfalse(原始字符串不是实例)

特殊值和新类型要注意的细节

ES2025 引入了 BigInt,ES2025 加入了 Temporal(暂未广泛支持),还有 PromiseMapWeakRef 等。它们都不能靠 typeof 准确识别,必须依赖 toString 或专用 API。

  • typeof 1n"bigint"(这是少数 typeof 能正确识别的新类型)
  • typeof Promise.resolve()"object",但 toString 返回 "[object Promise]"
  • Promise.resolve() instanceof Promisetrue(仅限当前 realm)
  • typeof window(浏览器中)→ "object",但 toString 返回 "[object Window]",不是标准类型

检测自定义类实例时,instanceof 最直接;检测内置对象类型时,toString 最稳;判断是否为原始值,可先用 typeof 快速分流,再针对性处理引用类型。