剖析「一起造轮子」的灵魂:3种实现instanceof的妙法
2023-09-04 01:54:50
在JavaScript中,instanceof运算符用于检测一个对象是否属于某个构造函数的实例。这个运算符的语法为:
instanceof <构造函数名>
例如,以下代码检测对象obj
是否属于构造函数Foo
的实例:
obj instanceof Foo
如果obj
属于Foo
的实例,则返回true
,否则返回false
。
instanceof运算符的原理是通过比较对象的原型链和构造函数的prototype属性。每个对象都有一个原型链,原型链是一个对象到另一个对象的引用链,最终指向Object.prototype
。构造函数的prototype属性指向该构造函数的原型对象。
如果实例对象的原型链上存在构造函数的prototype属性,则说明该实例对象属于该构造函数的实例。否则,该实例对象不属于该构造函数的实例。
接下来,我们就一起来「造轮子」,实现instanceof的3种不同写法:
第一种写法:原型链遍历
这种写法是最简单直接的,它通过遍历实例对象的原型链,来判断是否包含构造函数的prototype属性。如果包含,则返回true
,否则返回false
。
function instanceof(left, right) {
while (left !== null) {
if (left.__proto__ === right.prototype) {
return true;
}
left = left.__proto__;
}
return false;
}
第二种写法:Object.getPrototypeOf()
这种写法使用Object.getPrototypeOf()
方法来获取对象的原型对象。然后比较原型对象和构造函数的prototype属性,来判断是否相等。如果相等,则返回true
,否则返回false
。
function instanceof(left, right) {
let proto = Object.getPrototypeOf(left);
while (proto !== null) {
if (proto === right.prototype) {
return true;
}
proto = Object.getPrototypeOf(proto);
}
return false;
}
第三种写法:Reflect.getPrototypeOf()
这种写法使用Reflect.getPrototypeOf()
方法来获取对象的原型对象。然后比较原型对象和构造函数的prototype属性,来判断是否相等。如果相等,则返回true
,否则返回false
。
function instanceof(left, right) {
let proto = Reflect.getPrototypeOf(left);
while (proto !== null) {
if (proto === right.prototype) {
return true;
}
proto = Reflect.getPrototypeOf(proto);
}
return false;
}
以上便是「一起造轮子」实现instanceof的3种不同写法。这3种写法的原理都是一样的,都是通过比较对象的原型链和构造函数的prototype属性来判断是否相等。
最后,希望本文能帮助你对instanceof运算符和JavaScript原型链有一个更加深入的理解。