深入理解 JavaScript 中 instanceof 运算符的实现原理
本文通过代码示例与内存结构分析,深入解析 JavaScript 中 instanceof 运算符的工作原理。重点探讨对象 B 的 prototype 属性指向的对象是否在对象 A 的 [[prototype]] 链上这一核心机制,并详细解释当 prototype 被赋值为 null 时导致的异常行为及底层原因。

深入理解 JavaScript 中 instanceof 运算符的实现原理
那么,instanceof 运算符的这种行为究竟是如何实现的呢?现在让我们揭开 instanceof 背后的迷雾。
instanceof原理
代码示例分析
按照惯例,我们先来看一段代码示例:
代码如下:
function Cat(){}
Cat.prototype = {}
function Dog(){}
Dog.prototype ={}
var dog1 = new Dog();
alert(dog1 instanceof Dog);//true
alert(dog1 instanceof Object);//true
Dog.prototype = Cat.prototype;
alert(dog1 instanceof Dog);//false
alert(dog1 instanceof Cat);//false
alert(dog1 instanceof Object);//true;
var dog2= new Dog();
alert(dog2 instanceof Dog);//true
alert(dog2 instanceof Cat);//true
alert(dog2 instanceof Object);//true
Dog.prototype = null;
var dog3 = new Dog();
alert(dog3 instanceof Cat);//false
alert(dog3 instanceof Object);//true
alert(dog3 instanceof Dog);//error 内存结构分析
为了更直观地理解,我们绘制一张内存图来进行分析:

内存图相对复杂,这里进行简要解释:
程序运行是一个动态过程,随着代码执行,Dog.prototype 的指向会不断变化。为了便于说明,图中仅展示了一次静态快照,表达了 Dog.prototype 三次引用的变化。在堆内存中,右侧表示函数对象的内存结构,中间是函数对象 prototype 属性的指向,左侧则是通过函数创建的对象实例。函数对象指向 prototype 属性的指针上标注了 dog1、dog2、dog3,分别对应 Dog.prototype 的三次引用改变。它们与栈内存中的 dog1、dog2、dog3 变量也存在对应关系。(注:关于函数对象的详细讲解将在后续博文中展开)
有一点需要特别注意:当 dog3 对应的函数对象的 prototype 属性为 null 时,该函数对象实例 dog3 的内部 [[prototype]] 属性将指向 Object.prototype。这一点在《理解Javascript_06_理解对象的创建过程》一文中已有详细讲解。
结论与特殊情况
结论
根据代码运行结果和内存结构,我们可以推导出以下结论:
instanceof 用于检测对象 A 是否为对象 B 的实例,其原理是:查看对象 B 的 prototype 属性所指向的对象,是否存在于对象 A 的 [[prototype]] 链上。如果存在,则返回 true;如果不存在,则返回 false。不过存在一种特殊情况:当对象 B 的 prototype 属性为 null 时,将会报错(类似于空指针异常)。
这里推荐一篇来自岁月如歌的文章,同样探讨 instanceof 原理,虽然角度不同,但有着异曲同工之妙。
怎么用 Promise 封装 JavaScript sleep 函数实现异步延时
2026-11-05 17:49:14
什么时候该用JS构造器:与工厂模式、字面量的选择对比
2026-11-05 16:18:22
推荐几款轻量级JS照片墙开源库及对比
2026-11-05 15:56:19
JavaScript递归写法有哪些常见陷阱及避免方法
2026-11-05 14:53:38
JS数组浅拷贝与深拷贝怎么选?场景与方法总结
2026-11-05 14:41:02
