Object.prototype.toString.call 安全调用的前提是 this 不为 null 或 undefined;它不依赖 this 结构、不触发 getter/setter、无原型污染风险,但对 null/undefined 会抛错,且禁用 bind 后再 call;推荐用 x ?? {} 或 typeOf 封装处理边界。

直接调用 Object.prototype.toString.call 是安全的,无需额外“防护”,但需注意调用对象是否为 null 或 undefined —— 这是唯一会抛错的场景。
为什么它通常是安全的
Object.prototype.toString 本身是 JavaScript 内置方法,不依赖 this 值的特定结构,只要 this 不是 null 或 undefined,就能正常返回标准字符串(如 [object Array])。它不访问用户定义的属性或方法,也不会触发 getter/setter,因此不存在原型污染或意外副作用风险。
必须避免的两种调用方式
-
对 null 或 undefined 调用:例如
Object.prototype.toString.call(null)会抛出 TypeError。这是唯一明确禁止的输入。 -
误用 bind 后再 call:如
Object.prototype.toString.bind({}).call(obj),看似无害,实则绕过了原始方法绑定,可能因 this 绑定异常导致行为不可控,应直接 call,不建议中间 bind。
推荐的安全写法
对不确定是否为 null/undefined 的值,先做简单判断再调用:
- 用空值合并操作符兜底:
Object.prototype.toString.call(x ?? {}) - 或提前 guard:
if (x == null) return '[object Null]'; else return Object.prototype.toString.call(x); - 若用于类型判断,可封装为工具函数,统一处理边界情况:
return val == null
? `[object ${val === null ? 'Null' : 'Undefined'}]`
: Object.prototype.toString.call(val);
}
不要混淆:和 Object.toString() 的区别
obj.toString() 可能被重写(如数组、日期、自定义类),返回非标准结果;而 Object.prototype.toString.call(obj) 强制走原生逻辑,是获取准确内部 [[Class]] 标签的唯一可靠方式。这也是它被广泛用于类型检测的根本原因。

















