应使用 object.prototype.tostring.call(obj) 安全检测类型,它不依赖对象原型链,可正确返回如 [object array] 的标准字符串;避免 obj.tostring() 或 {}.tostring.call(obj)。

当对象的原型被显式设为 null(即创建了“无原型对象”),它将失去继承自 Object.prototype 的所有方法,包括 toString。直接调用 obj.toString() 就会报 TypeError: obj.toString is not a function。规避的核心思路是:不依赖实例自身的 toString 方法,而是通过其他可靠途径获取类型或字符串表示。
用 Object.prototype.toString.call() 安全检测类型
这是最推荐的做法。该方法不依赖目标对象的原型链,而是直接借用原生 Object.prototype.toString,对任意值(包括 null、undefined、无原型对象)都安全:
-
✅ 正确用法:
Object.prototype.toString.call(obj) -
❌ 避免:
obj.toString()(可能不存在)或{}.toString.call(obj)(若{}被篡改则不保险) - 返回形如
[object Object]、[object Array]、[object Null]的标准字符串,可用于精确类型判断
创建对象时保留必要原型,或手动挂载 toString
如果业务确实需要一个“几乎无原型但仍有基本方法”的对象,可折中处理:
- 用
Object.create(Object.prototype)替代Object.create(null),保留基础方法(含toString) - 若必须用
null原型,可手动添加最小化toString:const obj = Object.create(null); obj.toString = () => `[object ${obj.constructor?.name || 'Object'}]`; - 注意:手动挂载仅适用于你完全控制该对象的场景,且需自行维护一致性
用 typeof + Array.isArray() 等组合做轻量判断
对于不需要完整 toString 输出的场景,可绕过调用本身:
-
typeof obj === 'object'可区分对象/原始值(但null也返回'object') - 配合
obj === null单独判断null - 用
Array.isArray(obj)判断数组,obj instanceof Date等判断特定内置类型 - 适合日志、调试等对格式要求不严格的场合
封装安全的字符串化工具函数
在项目中统一处理,避免各处重复判断:
function safeToString(val) { return Object.prototype.toString.call(val); }- 或更进一步:
function safeStringify(val) { return val == null ? String(val) : Object.prototype.toString.call(val); } - 在工具库或全局 utils 中导出,团队内复用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











