object.prototype.tostring 是最可靠的类型检测方式,因其基于内部[[class]]标识返回如"[object array]"的字符串,不受原型污染、constructor篡改或跨iframe限制影响。

Object.prototype.toString 是 JavaScript 中最可靠、最通用的类型检测方式,它能准确识别内置对象类型,包括数组、日期、正则、Promise、Map、Set 等,不受原型链污染或 constructor 属性被篡改的影响。
为什么 toString 比 typeof 和 constructor 更可靠
typeof 只能区分基本类型(如 string、number)和 function,对对象一律返回 "object";constructor 容易被覆盖或继承干扰,无法识别跨 iframe 的对象。而 Object.prototype.toString.call(value) 借助内部 [[Class]] 标识(ES5 规范),返回形如 "[object Array]" 的字符串,稳定且可预测。
- Array.isArray([]) → true,但跨 iframe 失效;toString.call([]) → "[object Array]",始终有效
- new Date() instanceof Date → true,但在不同 window 下可能为 false;toString.call(new Date()) → "[object Date]",无环境依赖
- 自定义类实例的 constructor 可能被重写,但 toString 结果仍反映其真实内置类型(如 "[object Object]")
标准用法与常见类型映射
调用格式统一为 Object.prototype.toString.call(value),返回值需截取中间部分(去掉 "[object " 和 "]")来获取类型标识符。
- null → "[object Null]" → "Null"
- undefined → "[object Undefined]" → "Undefined"
- [] → "[object Array]" → "Array"
-
- new Map() → "[object Map]" → "Map"
- Promise.resolve() → "[object Promise]" → "Promise"
- BigInt(123) → "[object BigInt]" → "BigInt"
封装一个安全的类型判断工具
可基于 toString 封装一个简洁实用的 typeOf 函数,支持大小写不敏感匹配,并兼容 Symbol、ArrayBuffer 等较少见类型。
- 用 Object.prototype.toString.call(x).slice(8, -1) 提取类型名
- 转为小写便于比较,如 typeOf([1,2]) === 'array'
- 注意:普通对象返回 "Object",但不能区分 {a:1} 和 new (class {})() —— 它们都是 "[object Object]"
- 若需进一步区分自定义类,需结合其他手段(如 Symbol.toStringTag 或静态属性)
注意事项与边界情况
虽然 toString 很强大,但仍需留意几个细节:
- ES6+ 中部分内置对象(如 Proxy)调用 toString 仍返回 "[object Object]",不是其代理目标的类型
- 手动设置 Symbol.toStringTag 会影响结果,例如 obj[Symbol.toStringTag] = 'MyType' → "[object MyType]"
- 某些宿主对象(如 IE 中的 document.all)行为不一致,现代环境已基本无需考虑
- 性能上略低于 typeof,但类型判断通常不构成瓶颈,优先保证正确性











