跳到主要内容

typeof 类型判断怎么用?有哪些坑?

面试速答(30 秒版 TL;DR)

  • typeof 只可靠地区分 基本类型(primitive) 和少数特殊值:undefinedbooleannumberbigintstringsymbolfunctionobject
  • 最大坑:typeof null === "object"(历史遗留)。
  • typeof 对“未声明变量”不会抛错:typeof notDeclared 结果是 "undefined"(这点面试常考)。
  • 判断“具体对象类型”优先用:
    • Array.isArray(x) 判断数组
    • Object.prototype.toString.call(x) 判断内建对象([object Date] 等)
    • x instanceof Ctor 判断原型链关系(注意跨 iframe/realm 风险)

typeof 的返回值一览

typeof undefined; // "undefined"
typeof true; // "boolean"
typeof 1; // "number"
typeof 1n; // "bigint"
typeof "x"; // "string"
typeof Symbol("s"); // "symbol"
typeof function () {}; // "function"
typeof {}; // "object"
typeof []; // "object"
typeof null; // "object" // 坑

一句话心智模型:typeof 是“语言层面的粗分类”,不是“精确到类/构造函数”的类型系统。


典型题 & 标准答法

Q1:怎么区分 null / undefined

v === null; // 只匹配 null
v === undefined; // 只匹配 undefined
v == null; // 同时匹配 null 和 undefined(有意为之的宽松写法)

面试可说:typeof 区分不了 null,所以判断 null 用全等。

Q2:怎么判断数组、日期、正则?

Array.isArray(x); // 数组
Object.prototype.toString.call(x); // "[object Date]" / "[object RegExp]" / ...

Q3:为什么 typeof null"object"

答法要点:

  • 这是 JS 早期实现的历史 bug,后续为了兼容性保留。
  • 所以 null 判断要用 x === null

常见追问:typeof vs instanceof vs toString

  • typeof:适合判断 primitive、函数、是否未定义。
  • instanceof:判断“x 的原型链上是否出现过 Ctor.prototype”,适合同一运行时下的类实例判断。
  • Object.prototype.toString.call(x):适合判断内建对象类型(DateRegExpMapSetArguments 等),跨 realm 也通常更稳。

易错点/坑

  • typeof []"object",所以数组判断别用 typeof
  • 以为 typeof 能区分所有对象:不行,普通对象、数组、日期很多都是 "object"
  • instanceof Array 跨 iframe 可能失效(两个 realm 的 Array 构造函数不是同一个)。

速记要点(可背诵)

  • typeof 能稳判 primitive 和 function不能精确判对象
  • typeof null === "object" 是经典坑。
  • 数组用 Array.isArray,内建对象用 toString.call