返回

剖析「一起造轮子」的灵魂:3种实现instanceof的妙法

前端

在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原型链有一个更加深入的理解。