返回

剖析instanceof底层奥秘:手把手写一个instanceof

前端

壹 ❀ 引

本道题的核心考点还是对于javascript原型的掌握程度,比如__proto__prototype相关概念,以及instanceof底层原理的理解。若你对于原型已经非常熟悉,那么可以直

接跳到贰 ❀ 原型与__proto__进行学习。

javascript是一种基于原型的语言,对象可以通过其他对象来创建,而无需使用类。原型链是javascript对象的一个重要概念,它允许对象继承其他对象的属性和方法。每个对象都有一个原型,原型又可能拥有自己的原型,如此层层向上,直到到达最终的根原型——Object.prototype。任何对象都可以通过__proto__属性访问其原型。

instanceof操作符用于检测一个对象是否属于某个类的实例。其本质是检查该对象的原型链是否包含该类的原型。如果包含,则返回true;否则,返回false

为了更好地理解instanceof的底层原理,我们先从javascript中的原型说起。

贰 ❀ 原型与__proto__

在javascript中,每个对象都有一个原型,原型是一个指向另一个对象的指针。这个指针存储在对象的__proto__属性中。对象的__proto__属性指向其原型的引用,而原型的__proto__属性又指向其原型的引用,如此层层向上,直到到达最终的根原型——Object.prototype。如下图所示:

javascript原型链

原型链是一个重要的概念,它允许对象继承其他对象的属性和方法。例如,如果我们创建一个新的对象obj,并将其原型设置为Person.prototype,那么obj将继承Person.prototype中的所有属性和方法。这样,我们就可以使用obj.nameobj.sayHello()方法,即使这些属性和方法并不直接属于obj对象。如下图所示:

javascript原型继承

我们可以使用__proto__属性来访问对象的原型。例如,如果我们创建一个新的对象obj,并将其原型设置为Person.prototype,那么我们可以使用obj.__proto__来访问Person.prototype。如下图所示:

javascript访问对象的原型

我们可以使用Object.getPrototypeOf()方法来获取对象的原型。这个方法与__proto__属性的作用相同,都是获取对象的原型。但是,Object.getPrototypeOf()方法是标准的方法,而__proto__属性是非标准的属性。因此,在实际开发中,我们推荐使用Object.getPrototypeOf()方法来获取对象的原型。

叁 ❀ instanceof底层原理

instanceof操作符用于检测一个对象是否属于某个类的实例。其本质是检查该对象的原型链是否包含该类的原型。如果包含,则返回true;否则,返回false

instanceof操作符的底层实现非常简单,它只需要做以下几步:

  1. 获取对象的原型。
  2. 沿着原型的原型链向上查找,直到找到该类的原型。
  3. 如果找到该类的原型,则返回true;否则,返回false

以下是一个instanceof操作符的简单实现:

function instanceof(obj, Class) {
  while (obj) {
    if (obj === Class.prototype) {
      return true;
    }
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}

这个实现非常简单,它只需要沿着原型的原型链向上查找,直到找到该类的原型。如果找到该类的原型,则返回true;否则,返回false

肆 ❀ 手写instanceof

现在,我们已经了解了instanceof操作符的底层原理,那么我们就可以自己手写一个instanceof函数了。

以下是一个手写的instanceof函数:

function instanceof(obj, Class) {
  let proto = obj.__proto__;
  while (proto) {
    if (proto === Class.prototype) {
      return true;
    }
    proto = proto.__proto__;
  }
  return false;
}

这个函数与我们之前实现的instanceof函数非常相似,它只需要沿着原型的原型链向上查找,直到找到该类的原型。如果找到该类的原型,则返回true;否则,返回false

我们还可以使用Object.getPrototypeOf()方法来实现instanceof函数:

function instanceof(obj, Class) {
  let proto = Object.getPrototypeOf(obj);
  while (proto) {
    if (proto === Class.prototype) {
      return true;
    }
    proto = Object.getPrototypeOf(proto);
  }
  return false;
}

这个函数与我们之前实现的instanceof函数完全相同,它只需要沿着原型的原型链向上查找,直到找到该类的原型。如果找到该类的原型,则返回true;否则,返回false

伍 ❀ 结语

instanceof操作符是一个非常有用的操作符,它可以帮助我们检测一个对象是否属于某个类的实例。我们已经了解了instanceof操作符的底层原理,并且自己手写了一个instanceof函数。希望本文对您有所帮助。

感谢您的阅读!