深入理解 JavaScript 中 instanceof 运算符的实现原理

作者:闭包旅人时间:2026-10-25 11:11:37浏览:211

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

深入理解 JavaScript 中 instanceof 运算符的实现原理

深入理解 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

内存结构分析

为了更直观地理解,我们绘制一张内存图来进行分析:


深入理解 JavaScript 中 instanceof 运算符的实现原理

内存图相对复杂,这里进行简要解释:


程序运行是一个动态过程,随着代码执行,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 原理,虽然角度不同,但有着异曲同工之妙。

作者最新文章