Object.prototype.toString.call()是最可靠的JavaScript类型判断方法,它能准确识别null、数组、Date、RegExp等所有类型且不受跨iframe影响;typeof仅对函数准确,instanceof在跨环境时失效。
typeof 和 instanceof 都不能可靠判断所有 JavaScript 数据类型,尤其对 null、数组、内置对象(如 Date、RegExp)和跨 iframe 构造的实例会出错。
typeof null 返回 "object",这是历史遗留 bug;所有引用类型(除函数外)也都返回 "object",无法区分 Array、Date、RegExp 等。
typeof null → "object"(错误)typeof [] → "object"(无法识别是数组)typeof new Date() → "object"(同上)typeof function() {} → "function"(唯一准确的函数判断)instanceof 依赖构造函数的原型链比对,而不同 iframe 或 Worker 中的 Array、Promise 等构造函数是不同引用,导致判断失败。
[].constructor === window.parent.Array → false(即使值是数组)iframe.contentWindow.Array === Array → false
[1,2,3] instanceof iframe.contentWindow.Array → false(本该为 true)42、"str")永远返回 false
该方法能稳定返回内部 [[Class]] 标签,且不受全局环境影响,是目前最通用的类型检测基础。
Object.prototype.toString.call(42) // "[object Number]" Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call(/abc/) // "[object RegExp]" Object.prototype.toString.call(new Date())// "[object Date]" Object.prototype.toString.call(self) // "[object Window]"(在 iframe 中仍正确)
可封装为工具函数:
function typeOf(obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}
typeOf([1,2]) // "array"
typeOf(null) // "null"
typeOf(new Set()) // "set"
没有银弹。需按场景组合使用:
typeof fn === "function"(最安全)Array.isArray()(ES5+,不跨环境时最快)Object.prototype.toString.call()
instanceof 可用,但要确保构造函数来自同一全局上下文typeof 足够,但记得 null 单独处理多数现代库(如 Lodash 的 _.isXxx)底层都基于 toString.call 实现,因为它是唯一不被
环境隔离影响的通用机制。