typeof本质是读取引擎附加的“类型标签”并返回字符串,对基本类型精准,但null误判为object、所有非函数对象均返回"object",适合基础校验而非精确类型识别。

typeof 操作符本质是读取 JavaScript 引擎为每个值附加的“类型标签”(Type Tag),并返回对应的字符串。它快、轻量、安全,适合快速判断基本类型,但对引用类型识别粗糙,不能替代精准类型检测。
底层原理:靠类型标签直接查表
JavaScript 引擎在内存中存储值时,会为每个值打一个内部标记,标明它的原始类别。typeof 就是直接读这个标记,不执行构造函数检查、不遍历原型链、也不调用任何方法。
- 数字(number)类型标签为 0 → 返回 "number"
- 字符串(string)类型标签为 1 → 返回 "string"
- 布尔(boolean)为 2 → 返回 "boolean"
- undefined 为 3 → 返回 "undefined"
- Symbol 为 11,BigInt 为 12 → 分别返回 "symbol" 和 "bigint"
- null 的类型标签也是 0(和 number 相同),但引擎做了硬编码特殊处理 → 错误返回 "object"
核心局限性:三类典型失准场景
由于只看底层标签,不区分对象的具体结构或构造方式,typeof 在以下情况无法给出有意义的区分:
- null 被误判为 object:这是 V8 等引擎早期为兼容性保留的历史 bug,不是设计意图,但至今未修正
-
所有非函数对象统一返回 "object":数组
[]、日期new Date()、正则/abc/、Map、Set、自定义类实例……统统返回 "object" -
无法识别未声明变量的语法错误边界:虽然
typeof undeclared安全返回 "undefined",但它不等于“该变量存在且值为 undefined”,只是避免报错;真要确认变量是否存在,仍需结合作用域分析
什么情况下该用 typeof,什么不该用
明确它的定位,才能用得准:
-
推荐用:判断变量是否为
number、string、boolean、undefined、function或symbol—— 这些结果 100% 可靠 -
慎用或不用:区分
[]和{}、判断null、识别new Date()或Promise实例 —— 这些必须换方法 -
替代方案参考:
- 数组 →
Array.isArray() - null →
value === null - 精确对象类型 →
Object.prototype.toString.call(value)(返回"[object Array]"等) - 继承关系 →
instanceof(注意跨 iframe 失效)
- 数组 →
小结:它是类型检测的第一道筛子,不是万能锤
typeof 是轻量、安全、语义清晰的类型探针,特别适合防御性编程中的基础校验,比如函数入参预检:if (typeof cb !== 'function') throw new Error('Expected function')。但一旦涉及对象结构、运行时构造细节或跨环境一致性,就得交给更专业的工具。理解它“为什么这样返回”,比死记返回值更重要。











