跳到主要内容

typeofinstanceof 的区别是什么?

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

  • typeof:判断“值的原始类型标签”,对原始类型(除 null)好用;对对象只会给 "object"(函数是 "function")。
  • instanceof:判断“构造函数的 prototype 是否出现在对象的原型链上”,适合判断对象的具体实例(如 Date),不适合判断原始类型。
  • 常用组合:x === null(判 null) + Array.isArray(x)(判数组) + typeof x(判原始类型/函数) + x instanceof Xxx(判某类对象)。

心智模型:typeof 看“值”,instanceof 看“原型链”


typeof:返回的是字符串标签(对对象粒度粗)

常见返回值

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

适用场景

  • 判断是否未定义:typeof x === "undefined"(对“未声明变量”也安全)
  • 判断是否函数:typeof x === "function"
  • 判断是否原始类型(排除 null):x !== null && typeof x !== "object" && typeof x !== "function"

常见坑

  • typeof null === "object" 是历史 bug,判断 null 直接 x === null
  • typeof [] / typeof new Date() / typeof /re/ 都是 "object",无法细分对象子类型。

instanceof:看原型链是否“挂上了”某个 prototype

基本用法与直觉

const d = new Date();
d instanceof Date; // true
d instanceof Object; // true (Date 的原型链最终会到 Object.prototype)

对原始类型不适用(除非显式装箱)

1 instanceof Number; // false
new Number(1) instanceof Number; // true (但不推荐用包装对象)

它到底在比什么?(面试可口述)

核心逻辑等价于:

function myInstanceof(obj, Ctor) {
if (obj == null) return false;
let p = Object.getPrototypeOf(obj);
const target = Ctor.prototype;
while (p) {
if (p === target) return true;
p = Object.getPrototypeOf(p);
}
return false;
}

你可以把它理解为:obj.__proto__ 一路往上走,看有没有遇到 Ctor.prototype


典型题 & 标准答法

Q1:为什么 [] instanceof Array 为真,但 typeof [] 还是 "object"

  • typeof 对对象只给 "object"(函数除外),不区分数组/日期/正则。
  • instanceof 走原型链:数组对象的原型链上有 Array.prototype,所以为真。

Q2:什么时候 instanceof 会“不准”?

  • 跨 realm(例如 iframe)时:不同全局对象的 Array/Date 构造函数不是同一个引用,instanceof 可能失败。
  • 被篡改原型链时:如果对象的原型链被手动改过,也会影响结果。
  • 类支持自定义:类/函数可以通过 Symbol.hasInstance 改写 instanceof 行为(少见,但面试可以提一句“可被重载”)。

常见追问

  • “那数组/日期/正则怎么检测更稳?”
    • 数组:Array.isArray(x)
    • 日期:x instanceof Date(不跨 realm 时很好用)
    • 更通用:Object.prototype.toString.call(x),例如 "[object Date]""[object Array]"
  • “为什么判断 undefined 推荐用 typeof?”
    • 因为对未声明变量 typeof notDeclared 也不会抛错,结果仍是 "undefined"

易错点/坑(速记)

  • null:只能 x === null
  • 数组:优先 Array.isArray(x)
  • instanceof:本质是“原型链包含关系”,不是“类型标签”;跨 iframe 可能翻车。
  • 不要用 new Number/String/Boolean 作为业务数据类型。