最可靠的基础类型判断方式是 object.prototype.tostring.call(x),它返回标准化的 [object type] 字符串,不受自定义 tostring 干扰,能精确识别数组、null、日期等,且跨 iframe 稳定;封装后可统一提取小写类型名,支持多类型校验与 es6+ 内置类型。

JavaScript 中最可靠的基础类型判断方式,是利用 Object.prototype.toString 的原生行为——它能返回形如 [object Type] 的字符串,且不受对象自定义 toString 方法干扰。封装得当,就能获得比 typeof 更精确、比 instanceof 更通用的类型识别能力。
为什么不用 typeof 或 instanceof?
typeof 对数组、null、日期、正则等一律返回 "object" 或 "function",区分度低;instanceof 依赖原型链,在跨 iframe 或不同全局环境(如多个 window)下会失效。而 Object.prototype.toString.call(x) 是唯一能在所有环境中稳定返回内部 [[Class]] 标签的方法。
基础封装:统一提取类型名
核心是截取 [object X] 中的 X,并转为小写便于比较:
示例代码:
const typeOf = (val) => {
const raw = Object.prototype.toString.call(val);
return raw.slice(8, -1).toLowerCase();
};
typeOf([]); // 'array'
typeOf(null); // 'null'
typeOf(new Date()); // 'date'
typeOf(/a/g); // 'regexp'
typeOf(new Set()); // 'set'
增强判断:支持多类型校验与语义别名
可扩展为接受多个类型名,支持常见别名(如 'int' 指代 Number 且为整数),或组合判断:
- 用
Array.isArray()替代typeOf(arr) === 'array',性能略优但不通用;封装时仍建议统一走toString保持一致性 - 对
number进一步细分:配合Number.isInteger()判断是否为整数,Number.isNaN()区分NaN - 识别
Promise、Map、WeakMap等 ES6+ 内置类型,它们在各环境中的toString返回值已标准化 - 避免直接依赖构造函数名(如
val.constructor.name),因可能被改写或压缩工具破坏
实际使用建议
不必为每个判断都手写 Object.prototype.toString.call;封装成工具函数后,日常开发中可直接调用 typeOf(x) === 'map' 或 ['array', 'set', 'weakmap'].includes(typeOf(x))。注意它无法识别自定义类实例的具体类名(除非该类显式重写了 Symbol.toStringTag),此时需结合其他策略。











