Skip to content

一文搞懂instanceof方法

1.instanceof方法介绍和基本使用

instanceof 是 JavaScript 中常用于判断一个对象是否是某个特定类或构造函数的实例的运算符。它可以帮助你判断一个对象是否继承自特定类的原型链。

以下是一些 instanceof 方法的使用示例:

示例 1: 检查实例是否是特定构造函数(类)的实例

注意:是否是特定构造函数(类)的实例 或 构造函数的原型链的实例都可以

js
function Person(name) {
  this.name = name;
}

const person = new Person('John');
console.log(person instanceof Person);  // true
console.log(person instanceof Object);  // true,因为所有对象都是 Object 的实例
console.log(person instanceof Array);   // false,因为 person 不是数组的实例

示例 2: 检查继承关系

js
class Animal {
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(`${this.name} makes a sound.`);
  }
}

class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }

  bark() {
    console.log(`${this.name} barks.`);
  }
}

const dog = new Dog('Buddy', 'Labrador');
console.log(dog instanceof Dog);    // true
console.log(dog instanceof Animal); // true,因为 Dog 继承自 Animal
console.log(dog instanceof Object); // true,因为所有对象都是 Object 的实例
console.log(dog instanceof Array);  // false,因为 dog 不是数组的实例

示例 3: 使用 instanceof 判断自定义实例方法是否存在

js
function Car(make, model) {
  this.make = make;
  this.model = model;
}

Car.prototype.start = function() {
  console.log(`Starting the ${this.make} ${this.model}.`);
};

const myCar = new Car('Toyota', 'Corolla');
console.log(myCar instanceof Car); // true

// 检查是否有 start 方法
console.log(myCar instanceof Object); // true
console.log(myCar.start instanceof Function); // true

示例4:使用 instanceof 判断对象是否是对象的

2.Symbol.hasInstance方法

Symbol.hasInstance 是一个内置的 JavaScript 符号 (Symbol),用于自定义对象的 instanceof 运算符的行为。这个符号可以被用作对象的方法,用于判断一个对象是否是另一个对象的实例。

具体来说,当一个对象被用于 instanceof 运算符时(作为of后面的对象),JavaScript 引擎会调用该对象的 Symbol.hasInstance 方法。这个方法接受一个参数,即要检查的可能的实例对象。该方法应该返回一个布尔值,指示传入的对象是否为该对象的实例。

例如,可以创建一个自定义对象,并为其定义 Symbol.hasInstance 方法来自定义 instanceof 的行为:

js
const customObj = {
  [Symbol.hasInstance](instance) {
    return instance instanceof Array;
  }
};

console.log([] instanceof customObj);  // true
console.log({} instanceof customObj);  // false

在这个例子中,customObj 是一个包含 Symbol.hasInstance 方法的对象。该方法将检查传入的对象是否是数组的实例,并相应地返回布尔值。

请注意,Symbol.hasInstance 是一个静态的内置符号,你无法直接在你的代码中访问它,而是通过 [Symbol.hasInstance] 这种方式来使用。

3.instanceof的实现原理

instanceof 是 JavaScript 中用于检查对象是否属于某个类或构造函数的运算符。它的实现原理基于对象的原型链。下面是 instanceof 的简单实现原理:

  1. 首先,检查对象是否有 Symbol.hasInstance 方法。如果有,就调用这个方法来进行判断。这允许自定义类或构造函数来定义它们自己的 instanceof 行为。
  2. 如果对象没有 Symbol.hasInstance 方法,它会沿着原型链向上查找,直到找到 null 或与指定构造函数的 prototype 属性相等的原型对象。如果在这个过程中找到了匹配的原型对象,instanceof 返回 true;如果没有找到,返回 false

下面是一个简化版的 instanceof 实现:

js
function myInstanceOf(obj, constructorFn) {
  // 获取构造函数的原型对象
  const prototype = constructorFn.prototype;

  // 沿着原型链向上查找,直到为null
  while (obj !== null) {
    if (obj === prototype) {
      return true; // 在找的过程中如果遇到了相等的原型对象,即找到匹配的原型对象,那么就返回true
    }
    // 继续向上查找
    obj = Object.getPrototypeOf(obj);
  }

  return false; // 没有找到匹配的原型对象
}

这个 myInstanceOf 函数接受两个参数:要检查的对象 obj 和构造函数 constructorFn。它首先获取构造函数的原型对象 prototype,然后使用一个 while 循环来沿着 obj 的原型链向上查找。如果在查找过程中找到了匹配的原型对象,函数返回 true,否则返回 false