object.prototype.tostring.call() 是最可靠的类型检测方式,能精准识别内置对象类型,避开 typeof 和 instanceof 的缺陷;它读取 [[class]] 或 [[symbol.tostringtag]] 属性返回标准字符串,如 "[object array]",支持跨 iframe 环境,且可封装为通用 typeof 函数。

Object.prototype.toString.call() 是 JavaScript 中最可靠、最底层的类型检测方式,它能精准识别内置对象类型,避开 typeof 和 instanceof 的各种陷阱。
为什么 toString.call() 比 typeof 更准
typeof 对 null 返回 "object",对数组、正则、日期等都返回 "object" 或 "function",完全无法区分具体类型。而 Object.prototype.toString.call() 会读取对象内部的 [[Class]](ES5)或 [[Symbol.toStringTag]](ES6+)属性,返回标准格式字符串,例如:
-
Object.prototype.toString.call([])→"[object Array]" -
Object.prototype.toString.call(/a/g)→"[object RegExp]" -
Object.prototype.toString.call(null)→"[object Null]" -
Object.prototype.toString.call(undefined)→"[object Undefined]" -
Object.prototype.toString.call(new Date())→"[object Date]"
封装一个通用类型判断函数
直接每次写 Object.prototype.toString.call(x).slice(8, -1).toLowerCase() 太啰嗦,推荐封装成可复用的工具函数:
const typeOf = (val) => {
const raw = Object.prototype.toString.call(val);
return raw.slice(8, -1).toLowerCase();
};
使用示例:
-
typeOf([])→"array" -
typeOf(new Map())→"map" -
typeOf(Promise.resolve())→"promise" -
typeOf(new WeakSet())→"weakset"
注意:该方法对自定义类默认返回 "object",除非显式设置 Symbol.toStringTag。
处理 Symbol.toStringTag 自定义类型
ES6 允许对象通过 Symbol.toStringTag 控制 toString 输出,这对类型判定既是增强也是干扰点:
class MyType {}
MyType.prototype[Symbol.toStringTag] = 'MyType';
Object.prototype.toString.call(new MyType()); // "[object MyType]"
这意味着你的类型函数也能识别这类语义化标签,但需注意——它可被任意篡改,不具安全性,仅适用于可控或约定场景。
与 instanceof 的关键区别
instanceof 依赖原型链,跨 iframe 会失效;toString.call() 不依赖原型,只读内部标签,天然支持跨环境:
- 在 iframe 中创建的
[],arr instanceof Array为false(因构造函数不同) - 但
Object.prototype.toString.call(arr)仍返回"[object Array]"
所以涉及多窗口、插件沙箱或微前端时,toString.call() 是唯一稳健选择。










