javascript类型识别依赖运行时值,typeof仅适用于基本类型和函数但对null和引用类型不准;object.prototype.tostring.call()最精准,可区分所有内置类型;instanceof和constructor受原型链和跨环境限制;数组、nan、promise、plain object需针对性判断。

JavaScript类型识别完全依赖运行时值本身,没有编译期检查。判断结果不是由变量声明决定的,而是由当前实际持有的值、其底层表示和所处执行上下文共同决定的。安全识别的关键,在于理解每种方法的适用边界和失效场景。
typeof:快但有硬伤
它返回小写字符串(如"string"、"number"),适合快速筛查基本类型和函数。但它对null返回"object"(V8中因二进制标签全零导致的历史误判);对数组、正则、日期、错误等所有引用类型也统一返回"object";只有函数是例外,返回"function"。
- 安全用法:只用于检测
undefined、string、number、boolean、symbol、bigint、function - 必须规避:不用它判断
null(应直接用val === null),也不用它区分[]和{}
Object.prototype.toString.call():最精准的通用方案
这是唯一能稳定识别所有内置类型的通用方法。每个内置构造器(Array、Date、RegExp、Error等)内部都定义了不可篡改的[[Class]]标签,toString.call()可读取它:
-
Object.prototype.toString.call([])→ "[object Array]" -
Object.prototype.toString.call(null)→ "[object Null]" -
Object.prototype.toString.call(new Date())→ "[object Date]" -
Object.prototype.toString.call(/abc/)→ "[object RegExp]"
常封装为工具函数:const type = val => Object.prototype.toString.call(val).slice(8, -1).toLowerCase(),返回"array"、"null"、"date"等标准小写名。
instanceof 与 constructor:依赖原型链,跨环境易失效
obj instanceof Array检查obj.__proto__是否在Array.prototype链上;obj.constructor === Array则直接比构造函数。
- 优点:语义清晰,适合已知构造器来源的场景(如自己
new的实例) - 缺点:
instanceof在 iframe 或不同 JS 上下文中会失效(因为原型不共享);constructor可被手动修改,不可信,仅作辅助参考
特殊值需针对性判断
有些类型无法靠通用方法可靠识别,必须组合逻辑:
-
数组:优先用
Array.isArray()(ES5+,跨 iframe 安全) -
NaN:不能用
===(因为NaN !== NaN),必须用Number.isNaN()或全局isNaN()(注意后者会强制转数字) -
Promise:不能只看
typeof val.then === "function"(thenable 陷阱),应使用成熟库如is-promise -
Plain Object:排除
null、数组、内置类实例后,可用Object.getPrototypeOf(val) === Object.prototype
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











