真正可靠的类型判断需分层处理:先用 typeof 识别原始类型和 function,null 单独处理;对 typeof 为 "object" 且非 null 的值,同环境可用 instanceof,跨环境推荐 object.prototype.tostring.call() 或 array.isarray 等专用方法。

单独用 typeof 或 instanceof 都容易出错,真正可靠的类型判断需要分层处理:先用 typeof 快速识别原始类型,再对返回 "object" 的值做进一步甄别,必要时结合 instanceof 或更稳妥的方案。
先用 typeof 区分原始类型和对象边界
typeof 是第一道过滤器,它能准确识别所有原始类型(string、number、boolean、undefined、symbol、bigint)以及 function。遇到 null 时要单独处理——它虽是原始值,但 typeof null === "object" 是历史遗留问题。
- 直接用
typeof x === "string"判断是否为字符串(含字面量,不依赖构造函数) -
typeof x === "function"可靠识别函数,包括箭头函数、async 函数 -
typeof x === "object" && x !== null才代表“可能是引用类型”,进入下一步判断
对 object 类型,慎用 instanceof
instanceof 检查的是原型链上是否存在指定构造函数的 prototype,它只适用于同上下文的对象。跨 iframe、跨 window 时会失效(比如 iframe 里的数组在父页面 instanceof Array 返回 false)。
- 在可控环境(如单页应用主窗口内)可安全用于判断
Array、Date、RegExp等内置类型:arr instanceof Array - 注意继承关系:
[] instanceof Object也返回true,因为Array.prototype原型链最终指向Object.prototype - 原始值(如
"abc")用instanceof总是false,不要尝试
更通用、更安全的替代方案
当需要精确、跨环境兼容的类型识别时,Object.prototype.toString.call() 是最稳定的选择,它能返回标准的内部标签,不受构造函数污染或上下文隔离影响。
-
Object.prototype.toString.call([])→"[object Array]" -
Object.prototype.toString.call(/a/)→"[object RegExp]" -
Object.prototype.toString.call(null)→"[object Null]" - 封装成工具函数:
const typeOf = x => Object.prototype.toString.call(x).slice(8, -1).toLowerCase();
实际项目中的推荐组合
不必死记硬背规则,按场景选最简可靠方式:
- 判断数组:优先用
Array.isArray(x)(ES5+ 原生支持,语义明确,跨 iframe 安全) - 判断日期:
x instanceof Date(若确定同上下文),否则用typeOf(x) === "date" - 判断字符串或数字:直接
typeof x === "string"或typeof x === "number" - 判断是否为普通对象(非 null、非数组、非函数):
typeof x === "object" && !Array.isArray(x) && x !== null && !(x instanceof Function)











