typeof对基础类型基本可靠,但null返回"object",nan/infinity/数字字面量均返回"number";array.isarray是唯一靠谱的数组检测方式,es5标准,跨iframe安全且语义明确。

typeof 识别基础类型时的常见误判
typeof 对基础类型基本可靠,但有两个经典坑:null 返回 "object",而 NaN、Infinity、数字字面量(如 42)都返回 "number"——它不区分有效数与非数。
实际判断时别直接信 typeof x === "number" 就代表可计算;得配合 isFinite(x) 或 Number.isNaN(x) 二次确认。
另外,typeof new Number(42) 是 "object",而 typeof 42 是 "number",包装对象和原始值行为不一致,日常应避免用 new Number / new String。
Array.isArray 是唯一靠谱的数组检测方式
别用 typeof [] === "object"、instanceof Array 或 Object.prototype.toString.call([]) === "[object Array]" 来判断数组——前两者跨 iframe 失效,后者冗长且易写错字符串。
Array.isArray 是 ES5 标准方法,浏览器兼容到 IE9+,Node.js 全版本支持,语义明确、性能好、无环境陷阱。
常见误用场景:
- 用
arr.constructor === Array:子类数组或自定义构造函数会失败 - 依赖
arr.length !== undefined:类数组对象(如arguments、NodeList)也满足 - 检查
arr.push是否存在:字符串也有push(在某些错误挂载下)或根本没该方法但不报错
联合使用时的优先级与边界情况
想同时区分 null、基础类型、普通对象、数组?顺序很重要。先用 Array.isArray 单独抓数组,再用 typeof 分基础类型,最后用 x === null 或 Object.prototype.toString 补漏。
例如这个判断逻辑:
if (Array.isArray(x)) {
return 'array';
} else if (x === null) {
return 'null';
} else if (typeof x === 'object') {
return 'plain object';
} else if (typeof x === 'string' || typeof x === 'number' || typeof x === 'boolean' || typeof x === 'undefined' || typeof x === 'symbol' || typeof x === 'bigint') {
return typeof x;
}
注意:typeof 永远不会返回 "null",所以 null 必须显式比较;typeof 对函数返回 "function",但它本质是 object 的子类,是否归为“对象”取决于你的业务定义。
TypeScript 中 typeof 与 Array.isArray 的类型提示差异
TypeScript 的 typeof 操作符在类型层面只反映运行时基础类型(如 string、number),对数组它推导为 any[] 或具体泛型(如 string[]),但不会变成 Array<t></t> 类型名。
而 Array.isArray 在类型守卫中能触发类型收窄——加上 if (Array.isArray(x)) { ... } 后,TS 知道块内 x 是 unknown[] 或更精确的数组类型。
所以写类型守卫时优先用 Array.isArray,而不是靠 typeof x === "object" 再手动断言——后者无法触发自动收窄,容易漏掉 null 或其他对象。
容易被忽略的是:即使你写了 Array.isArray(x),如果 x 类型是 any 或 unknown,TS 仍允许后续任意属性访问;真正安全的前提是变量有初始类型约束,否则守卫只是运行时防护,不是编译期保障。










