instanceof 和 typeof 的区别:什么时候该用哪个?

一、写在前面

面试高频、代码高频,却依旧让前端同学心里打鼓的三连问:

"typeof 不够吗?"

"instanceof 到底靠不靠谱?"

"手动修改 prototype 会怎样?"

今天,咱们把 instanceof 拉进实验室,做一次彻底的"DNA 检测"。


二、语法速写

javascript 复制代码
object instanceof Constructor  // 返回布尔值

左边:待检测的"孩子"

右边:疑似"父母"的构造函数

一句话:孩子是不是这家生的?


三、核心原理:原型链"家谱"查找

  1. 取孩子的隐式原型:Object.getPrototypeOf(obj)
  2. 取父母的"出生证明":Constructor.prototype
  3. 一级一级往上翻家谱,直到:
    • 找到相同的祖先 → 返回 true
    • 翻到 null 还没找到 → 返回 false

伪代码还原引擎逻辑:

javascript 复制代码
function instanceOf(obj, Ctor) {
  if (typeof obj !== 'object' || obj === null) return false;
  let proto = Object.getPrototypeOf(obj);
  while (proto) {
    if (proto === Ctor.prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
  return false;
}

四、三张图看懂全过程

(文本版)

javascript 复制代码
obj ──proto──> Dog.prototype ──proto──> Animal.prototype ──proto──> Object.prototype ──null
检测表达式 结果 原因说明
d instanceof Dog true 第一层就匹配
d instanceof Animal true 第二层匹配
d instanceof Object true 最终层匹配
d instanceof Cat false 整个链都没出现 Cat.prototype

五、四个容易翻车的场景

  1. 原始值一律 false
    "abc" instanceof String // false

    (包装类 new String('abc') 才行)

  2. 跨 iframe 失效

    窗口 A 的 [] 与窗口 B 的 Array 不是同一份 Array.prototype

  3. 手动篡改 prototype

    javascript 复制代码
    function F() {}
    const o = new F();
    F.prototype = {};     // 出生证明被撕了
    console.log(o instanceof F); // false
  4. Symbol.hasInstance ------ 黑科技拦截

    javascript 复制代码
    class MyArray {
      static [Symbol.hasInstance](obj) {
        return Array.isArray(obj) && obj.length > 3;
      }
    }
    [1,2,3,4] instanceof MyArray; // true
    [1,2] instanceof MyArray;     // false

    从 ES6 起,引擎优先调用静态方法 Symbol.hasInstance,把"家谱查找"变成"自定义卷子"。


六、instanceof vs typeof 速查表

场景 typeof 结果 instanceof 结果 备注
[] 'object' Array typeof 只能区分数组对象
{} 'object' Object 无法区分数组与普通对象
new String('') 'object' String 包装类
function fn(){} 'function' Function typeof 唯一能识函数
null 'object' 任意都 false 历史 Bug

七、实战:写一个"安全数组"检测器

javascript 复制代码
const isArray = value => Array.isArray(value) || value instanceof Array;
// 二者等价,但 Array.isArray 更快且跨 iframe 安全

八、小结口诀

"instanceof 不看户口,只看家谱;

家谱可改,Symbol 能挡;

原始值直接拜拜,跨窗面试常踩坑。"


九、延伸思考

  1. 能否用 Object.create(null) 骗过所有 instanceof
  2. 如何给自定义类实现"多重身份"?(提示:mixin + Symbol.hasInstance)

(把本文所有代码片段跑一遍,面试手写不怕卡壳。)


如果这篇"家谱探秘"帮你理清思路,点个 ⭐ 吧!

评论区告诉我:你在哪个场景被 instanceof 坑过?

相关推荐
道一2321 分钟前
在Electron应用中控制剪贴板操-复制&粘贴
前端·javascript·electron
xulihang23 分钟前
如何在Windows上使用SANE扫描文档
linux·前端·javascript
fruge1 小时前
前端错误监控与上报:Sentry 接入与自定义告警规则
前端·sentry
敲敲了个代码1 小时前
11月3-5年Web前端开发面试需要达到的强度
前端·vue.js·学习·react.js·面试·职场和发展·web
曼巴UE51 小时前
UE5 C++ JSON 最简单,麻烦的方式,直接读存(一)
java·服务器·前端
半桶水专家1 小时前
Vue Pinia 插件详解
前端·javascript·vue.js
吃饺子不吃馅1 小时前
面试官:JWT、Cookie、Session、Token有什么区别?
前端·设计模式·面试
IT_陈寒1 小时前
React 19新特性实战:5个提升开发效率的技巧与避坑指南
前端·人工智能·后端
丙寅2 小时前
微信小程序反编译遇到 TypeError: _typeof3 is not a function
开发语言·javascript·ecmascript
青衫码上行2 小时前
【Java Web学习 | 第十篇】JavaScript(4) 对象
java·开发语言·前端·javascript·学习