Object.prototype.toString.call 是安全准确的类型检测方法,不能切换类型;它能精确区分内置对象类型,绕过重写的 toString,返回如 "[object Array]" 的字符串,可封装为 typeOf 工具函数提取类型名。

Object.prototype.toString.call 并不用于“类型切换”,它只是一个安全、准确的类型检测方法,无法改变变量的实际类型。JavaScript 中类型是动态且不可变的,所谓“切换”其实是创建新值或转换值的表现形式。
为什么用 Object.prototype.toString.call 检测类型?
相比 typeof 和直接调用 toString(),它能更精确地区分内置对象类型:
-
typeof []返回"object",无法识别数组;而Object.prototype.toString.call([])返回"[object Array]" -
{}、new Date()、/regex/等都返回"object"(typeof的局限),但toString.call可分别得到"[object Object]"、"[object Date]"、"[object RegExp]" - 它绕过了实例上可能被重写的
toString方法,保证结果可靠
常见类型检测写法
可封装成简洁的工具函数:
const typeOf = (val) => {
return Object.prototype.toString.call(val).slice(8, -1).toLowerCase();
};
// 使用示例:
typeOf([]); // "array"
typeOf(null); // "null"
typeOf(undefined); // "undefined"
typeOf(new Set()); // "set"
typeOf(123); // "number"
它不能“切换类型”,但可辅助类型转换
检测之后,你才能决定如何安全转换——这属于业务逻辑,不是 toString.call 的职责:
- 检测到
"number"后,可用String(num)转字符串 - 检测到
"string"且想转为数字,用Number(str)或parseInt(str),注意处理NaN - 检测到
"object"且是类数组(如arguments),可用Array.from()转真数组
注意边界情况
某些宿主对象(如 IE 中的 document.all)或自定义对象可能返回非标准字符串,但现代环境基本稳定。另外:
- ES6+ 新增类型如
BigInt、Symbol、Promise均能被正确识别(如"[object bigint]") - 自定义类实例默认返回
"[object Object]",除非显式修改Symbol.toStringTag - 不要依赖返回字符串的大小写或空格——始终用
.slice(8, -1)提取标签名

















