typeof 类型判断怎么用?有哪些坑?
面试速答(30 秒版 TL;DR)
typeof只可靠地区分 基本类型(primitive) 和少数特殊值:undefined、boolean、number、bigint、string、symbol、function、object。- 最大坑:
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):适合判断内建对象类型(Date、RegExp、Map、Set、Arguments等),跨 realm 也通常更稳。
易错点/坑
typeof []是"object",所以数组判断别用typeof。- 以为
typeof能区分所有对象:不行,普通对象、数组、日期很多都是"object"。 - 用
instanceof Array跨 iframe 可能失效(两个 realm 的Array构造函数不是同一个)。
速记要点(可背诵)
typeof能稳判 primitive 和function,不能精确判对象。typeof null === "object"是经典坑。- 数组用
Array.isArray,内建对象用toString.call。