Object.prototype.toString.call()通过规范定义的标准化流程识别类型:null/undefined直接返回对应字符串,其余值经ToObject转为包装对象后读取内部[[Class]]属性,输出"[object Xxx]"格式;它比typeof更精准,因不受历史bug和原型重写影响。
![如何理解 object.prototype.tostring.call() 识别原始类型内部 [[class]] 的机制](https://img.php.cn/upload/article/001/242/473/177796779652793.png?x-oss-process=image/resize,p_40)
Object.prototype.toString.call() 能识别原始类型(如 1、"abc"、true、null、undefined)的内部 [[Class]],靠的不是“对象本身有这个属性”,而是 JavaScript 引擎在调用该方法时的一套标准化处理流程。
原始值会被临时包装成对应对象
JavaScript 规范规定:当原始值(number/string/boolean)作为 this 传入 Object.prototype.toString 时,引擎会先执行 ToObject(this) 操作——也就是把它们自动转为对应的包装对象:
-
1→new Number(1)→ [[Class]] 是"Number" -
"hello"→new String("hello")→ [[Class]] 是"String" -
false→new Boolean(false)→ [[Class]] 是"Boolean"
这个过程是隐式的、瞬时的,不改变原值,只为让 toString 能读取其 [[Class]]。
null 和 undefined 是特例,由规范直接定义
它们没有构造函数,也不能被包装成对象,但规范明确要求:
- 若
this是null,直接返回"[object Null]" - 若
this是undefined,直接返回"[object Undefined]"
这不是从某个对象上读出来的,而是算法步骤中硬编码的分支判断,确保结果稳定可靠。
最终输出统一格式:"[object Xxx]"
无论输入是原始值还是对象,整个流程都遵循固定逻辑:
- 先检查
this是否为null或undefined,是则直接返回对应字符串 - 否则调用
ToObject(this)得到一个对象O - 读取
O的内部属性 [[Class]](只读、不可篡改) - 拼接成
"[object " + [[Class]] + "]"
所以 Object.prototype.toString.call(42) 返回 "[object Number]",本质是“42 被临时当成 Number 实例,它的 [[Class]] 就是 Number”。
为什么它比 typeof 更准?
typeof 是操作符,设计目标是快速分类运行时基本类别,因此:
-
typeof null错误返回"object"(历史 bug,未修复) -
typeof []、typeof new Date()全是"object",无法区分
而 Object.prototype.toString.call() 不依赖变量声明方式或原型链,只读取引擎内置的 [[Class]] 标签,这个标签对每种内置类型都有唯一、确定的值,且不可被用户代码覆盖。










