object.prototype.tostring.call(value) 是检测 javascript 精确类型的最可靠方式,它通过读取目标值的 [[class]] 或 symbol.tostringtag 内部属性返回标准字符串(如 "[object array]"),需用 call 绑定 this 才能正确识别类型。

直接调用 Object.prototype.toString.call(value) 是 JavaScript 中检测精确类型最可靠的方式,它绕过了实例自身的 toString 方法,利用原型链上原始的、未被覆盖的 Object 构造函数的 toString 实现。
为什么 Object.prototype.toString 能精准识别类型?
ECMAScript 规范规定,Object.prototype.toString 内部会读取目标值的 [[Class]] 内部属性(ES5)或 Symbol.toStringTag(ES6+),并返回形如 "[object Array]"、"[object Date]" 的字符串。这个行为对所有内置对象(Array、Date、RegExp、Map、Set 等)和基本包装类型都一致,且不可轻易伪造(除非显式设置 Symbol.toStringTag)。
如何正确借用它检测类型?
必须用 call 或 apply 显式绑定 this 到待检测值,否则直接调用 Object.prototype.toString() 会固定返回 "[object Object]"(因为此时 this 是原型对象本身)。
-
✅ 正确写法:
Object.prototype.toString.call([])→"[object Array]" -
✅ 正确写法(封装函数):
function typeOf(obj) { return Object.prototype.toString.call(obj).slice(8, -1); } typeOf([1, 2]) // "Array" typeOf(new Date()) // "Date" -
❌ 错误写法:
Object.prototype.toString([])或{}.toString.call([])(后者可能被污染)
常见类型检测结果对照表
以下为典型返回值(括号内为 .slice(8, -1) 后的结果):
-
[object Array]→"Array" -
[object Object]→"Object"(纯普通对象,非 null) -
[object Date]→"Date" -
[object RegExp]→"RegExp" -
[object Map]→"Map" -
[object Set]→"Set" -
[object Null]→"Null"(ES6+ 支持,IE 不支持) -
[object Undefined]→"Undefined"(同上) -
[object Promise]→"Promise"
注意边界与兼容性
该方法在绝大多数环境下稳定,但需留意:
- 自定义类若设置了
Symbol.toStringTag,会覆盖默认行为(例如class MyClass { get [Symbol.toStringTag]() { return 'MyClass'; } }) - IE8 及更早版本不支持
Object.prototype.toString对某些内置类型的区分(如Array和Object都返回"[object Object]") - 不能替代
instanceof检测自定义构造函数实例(因原型链可被修改),但它能识别“是什么”,而非“由谁构造”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











