在 JavaScript 中,instanceof
操作符用于检查一个对象是否是某个构造函数的实例。具体来说,它用来判断对象的原型链中是否存在构造函数的 prototype
属性。
instanceof
的实现原理
instanceof
操作符的基本原理是基于原型链的逐层查找过程:
对象的
__proto__
指针:每个对象在创建时会自动关联到某个原型对象,这个原型对象通过对象的__proto__
指针来引用。构造函数的
prototype
属性:每个构造函数(如Array
、Object
)都有一个prototype
属性,指向一个原型对象。这个原型对象包含了所有实例共享的属性和方法。原型链查找:
instanceof
会从目标对象的__proto__
开始,沿着原型链一级一级查找,看是否能够找到构造函数的prototype
属性所指向的那个原型对象。返回结果:如果在原型链中找到构造函数的
prototype
属性,instanceof
返回true
,否则返回false
。
代码示例
1 | function Person() {} |
在这个例子中:
Person
是一个构造函数,它的prototype
属性指向{}
(一个空的对象)。john
是通过Person
构造函数创建的实例。john
的__proto__
指针指向Person.prototype
。john instanceof Person
会沿着john.__proto__
查找,发现它指向Person.prototype
,所以返回true
。- 因为
Person.prototype
的原型是Object.prototype
,所以john instanceof Object
也返回true
。
instanceof
的内部实现过程
假设我们要判断 object instanceof Constructor
:
- 取得
object
的原型,赋值给一个变量proto
,即proto = object.__proto__
。 - 取得
Constructor
的prototype
属性,赋值给prototype
。 - 循环检查
proto
是否严格等于prototype
。- 如果相等,则返回
true
。 - 如果
proto
为null
,说明到达原型链的顶端,还未找到,返回false
。 - 否则,继续沿着原型链查找,更新
proto = proto.__proto__
。
- 如果相等,则返回
实现一个简单的 instanceof
我们可以用 JavaScript 模拟实现 instanceof
的基本逻辑:
1 | function myInstanceof(object, constructor) { |
特殊情况
- 原始类型:对于
null
和undefined
,instanceof
无法使用,因为它们没有原型链,会直接返回false
。 - 自定义类型继承:如果构造函数的
prototype
被重新赋值为其他对象,实例也会相应受到影响,instanceof
结果会发生变化。
1 | function Animal() {} |
小结
instanceof
的原理在于通过原型链逐层查找,将对象的 __proto__
与构造函数的 prototype
进行比对。因此,instanceof
能准确判断对象和构造函数的继承关系,只要 prototype
没有被修改。