javaScript有8种数据类型,typeof因历史bug和无法区分对象子类型而不够用;Object.prototype.toString.call()是最可靠判断方法,可精确识别所有内置类型。

javascript 有 8 种数据类型:7 种原始类型(string、number、Boolean、NULL、undefined、symbol、bigint)和 1 种引用类型(object,包括 Array、function、date、regexp、map、Set 等所有非原始值)。
为什么 typeof 不够用?
typeof 是最常用的方法,但它在几个关键地方会“撒谎”:
-
typeof null === 'object'—— 这是历史 bug,至今未修复 -
typeof [] === 'object'、typeof {} === 'object'、typeof new Date() === 'object'—— 全部返回'object',无法区分具体类型 -
typeof function(){} === 'function'虽然正确,但function本质仍是object,只是被特殊对待
准确判断类型的推荐方法:Object.prototype.toString.call()
这是最可靠、兼容性最好、且能区分内置对象类型的方式。它利用每个内置构造函数在内部定义的 [[class]] 标签(ES5 规范),返回形如 "[object Array]" 的字符串:
-
Object.prototype.toString.call([])→"[object Array]" -
Object.prototype.toString.call(null)→"[object Null]" -
Object.prototype.toString.call(undefined)→"[object Undefined]" -
Object.prototype.toString.call(new Set())→"[object Set]" -
Object.prototype.toString.call(42n)→"[object BigInt]"
你可以封装一个通用判断函数:
立即学习“Java免费学习笔记(深入)”;
function getType(value) { return Object.prototype.toString.call(value).slice(8, -1); } // getType([]) → 'Array' // getType(Promise.resolve()) → 'Promise' // getType(/abc/) → 'RegExp'
针对特定场景的快捷判断
实际开发中,常结合语义和性能做取舍:
- 判数组:
Array.isArray(arr)—— 最快最标准(比toString略快,且可读性强) - 判函数:
typeof fn === 'function'—— 安全可靠,无需绕路 - 判空值:
value == null(等价于value === null || value === undefined) - 判原始值:
typeof value !== 'object' && typeof value !== 'function',或更严谨地Object(value) !== value
注意 Symbol 和 BigInt 的兼容性
Symbol 和 BigInt 在较老环境(如 IE、node.js toString.call 判断时,它们会正常返回 "Symbol" 和 "BigInt",但若需降级处理,建议先检测全局是否存在对应构造器:
typeof Symbol === 'function'typeof BigInt === 'function'
现代项目(如用 Babel 或目标环境明确)基本无需担心。
基本上就这些。记牢 Object.prototype.toString.call() 是“终极答案”,再按需搭配 Array.isArray、typeof 等快捷方式,就能稳准狠地识别任意 js 值的类型。