JavaScript类型识别依赖运行时值与上下文,无编译期检查;typeof快但对null和引用类型不准;Object.prototype.toString.call()最精准,可识别所有内置类型;instanceof和constructor受原型链限制;特殊类型需针对性判断如Array.isArray()、Number.isNaN()等。

JavaScript类型识别不是靠声明,而是靠运行时值本身和上下文。它没有编译期类型检查,所有判断都发生在代码执行中,引擎根据底层二进制标签、对象结构、原型链和使用场景动态推断。
typeof:快但有硬伤
最常用,返回小写字符串(如 "string"、"number"),适合快速筛查基本类型。但它对 null 返回 "object"(V8 中因全零二进制标签误判);对数组、正则、日期等也统一返回 "object";函数是唯一例外,返回 "function"。
- 安全用法:只用于检测 undefined、string、number、boolean、symbol、bigint、function
- 必须规避:不用它判断 null 或区分数组与普通对象
- 示例:
typeof [] === "object"✅;typeof null === "object"❌(需单独val === null)
Object.prototype.toString.call():精准的“身份证扫描”
这是唯一能稳定识别所有内置类型的通用方案。每个内置构造器(Array、Date、RegExp 等)在内部都定义了对应的 [[Class]] 标签,toString.call() 能读取它:
-
Object.prototype.toString.call([])→ "[object Array]" -
Object.prototype.toString.call(null)→ "[object Null]" -
Object.prototype.toString.call(new Date())→ "[object Date]"
封装成工具函数很常见:const type = val => Object.prototype.toString.call(val).slice(8, -1).toLowerCase(),返回 "array"、"null"、"date" 等标准小写名。
立即学习“Java免费学习笔记(深入)”;
instanceof 与 constructor:依赖原型链,慎用于跨环境
obj instanceof Array 检查 obj.__proto__ 是否在 Array.prototype 链上;obj.constructor === Array 直接比构造函数。
- 优点:语义清晰,适合已知构造器来源的场景(如自己 new 的类实例)
- 缺点:iframe 或不同 JS 上下文中,
Array不共享原型,instanceof会失效 - constructor 可被手动修改,不可信,仅作辅助参考
特殊值与场景的针对性判断
有些类型无法靠通用方法可靠识别,需组合逻辑:
-
数组:优先用
Array.isArray()(ES5+,跨 iframe 安全) -
NaN:不能用
===(NaN !== NaN),必须用Number.isNaN()或isNaN()(注意后者会强制转数字) -
Promise:不能只看
typeof val.then === "function"(thenable 陷阱),应使用成熟库如is-promise或who-is-actor -
Plain Object:排除 null、数组、内置类实例后,可用
Object.getPrototypeOf(obj) === Object.prototype


















