Learn JavaScript

isPrototypeOf() - метод для проверки прототипа объекта в JavaScript

isPrototypeOf() проверяет, находится ли один объект в цепочке прототипов другого объекта.

Это важно понимать сразу: метод не сравнивает сами объекты между собой, а отвечает на вопрос, является ли один объект прототипом другого.

Синтаксис

proto.isPrototypeOf(object)

proto - объект, который мы считаем возможным прототипом.

object - объект, у которого проверяется цепочка прототипов.

Что делает isPrototypeOf()

Если объект proto находится в цепочке прототипов object, метод вернёт true.

const animal = {};
const dog = Object.create(animal);

console.log(animal.isPrototypeOf(dog)); // true

Здесь animal действительно является прототипом dog.

Что возвращает isPrototypeOf()

isPrototypeOf() всегда возвращает булево значение:

  • true, если объект найден в цепочке прототипов
  • false, если не найден
const base = {};
const obj = Object.create(base);

console.log(base.isPrototypeOf(obj)); // true
console.log(obj.isPrototypeOf(base)); // false

Проверяется вся цепочка прототипов

Метод ищет не только прямой прототип, а всю цепочку целиком.

const animal = {};
const dog = Object.create(animal);
const puppy = Object.create(dog);

console.log(animal.isPrototypeOf(puppy)); // true
console.log(dog.isPrototypeOf(puppy));    // true

Хотя animal не является прямым прототипом puppy, он всё равно находится выше в цепочке.

Если объекта в цепочке нет

Если объект не найден в цепочке прототипов, результат будет false.

const animal = {};
const car = {};

console.log(animal.isPrototypeOf(car)); // false

Прямой прототип и вся цепочка

Если нужен только прямой прототип, чаще используют Object.getPrototypeOf().

const animal = {};
const dog = Object.create(animal);

console.log(Object.getPrototypeOf(dog) === animal); // true

isPrototypeOf() идёт шире и проверяет всю цепочку.

isPrototypeOf() и Object.getPrototypeOf()

Эти методы похожи, но отвечают на разные вопросы.

const animal = {};
const dog = Object.create(animal);

console.log(animal.isPrototypeOf(dog)); // true
console.log(Object.getPrototypeOf(dog)); // animal

isPrototypeOf() возвращает true или false.

Object.getPrototypeOf() возвращает сам прототип объекта.

isPrototypeOf() и instanceof

Эти проверки тоже часто путают.

function Animal() {}

const dog = new Animal();

console.log(Animal.prototype.isPrototypeOf(dog)); // true
console.log(dog instanceof Animal);               // true

instanceof обычно используют с функцией-конструктором или классом.

isPrototypeOf() работает напрямую с объектом-прототипом.

Пример с Object.prototype

Почти у всех обычных объектов в цепочке есть Object.prototype.

const user = {};

console.log(Object.prototype.isPrototypeOf(user)); // true

Это работает и для массивов:

const arr = [];

console.log(Object.prototype.isPrototypeOf(arr)); // true
console.log(Array.prototype.isPrototypeOf(arr));  // true

Если передать примитив

Если передать не объект, метод вернёт false.

const proto = {};

console.log(proto.isPrototypeOf(123));      // false
console.log(proto.isPrototypeOf("hello"));  // false
console.log(proto.isPrototypeOf(null));     // false

Object.create(null)

Если объект создан через Object.create(null), у него нет Object.prototype в цепочке.

const dict = Object.create(null);

console.log(Object.prototype.isPrototypeOf(dict)); // false

Это полезно помнить при работе с объектами без прототипа.

isPrototypeOf() не меняет объекты

Метод только проверяет цепочку прототипов и ничего не изменяет.

const base = {};
const obj = Object.create(base);

const result = base.isPrototypeOf(obj);

console.log(result); // true
console.log(obj);    // {}

Когда это полезно

isPrototypeOf() удобно использовать, когда:

  • нужно проверить прототипное наследование напрямую
  • под рукой есть именно объект-прототип, а не конструктор
  • важно понять, находится ли объект где-то в цепочке прототипов

Пример:

const person = {
  greet() {
    console.log("Hi");
  },
};

const user = Object.create(person);

console.log(person.isPrototypeOf(user)); // true

Частые ошибки

Думать, что метод сравнивает два объекта на равенство

const a = {};
const b = {};

console.log(a.isPrototypeOf(b)); // false

Это не проверка на равенство объектов.

Путать прямой прототип и всю цепочку

const a = {};
const b = Object.create(a);
const c = Object.create(b);

console.log(a.isPrototypeOf(c)); // true

Хотя a не является прямым прототипом c, он всё равно найден в цепочке.

Путать isPrototypeOf() и instanceof

function User() {}
const user = new User();

console.log(User.prototype.isPrototypeOf(user)); // true

Здесь метод вызывается у объекта-прототипа, а не у конструктора User.

Быстрая памятка

  • isPrototypeOf() проверяет, находится ли объект в цепочке прототипов другого объекта
  • метод возвращает true или false
  • проверяется вся цепочка, а не только прямой прототип
  • instanceof работает через конструктор, а isPrototypeOf() - через объект-прототип
  • метод не меняет объекты

Коротко

isPrototypeOf() - это способ проверить прототипное наследование напрямую. Главное, что стоит запомнить: метод отвечает на вопрос, есть ли один объект в цепочке прототипов другого, а не сравнивает сами объекты между собой.