Работа с прототипированым наследованием в JavaScript

Дан объект:

const object = {
    foo: 1
};

Если выполнить:

console.log([
    'foo' in object,                    
    'toString' in object,               
    object.hasOwnProperty('foo'),       
    object.hasOwnProperty('toString')  
]);

Какие логические значения в console.log будут получены?

Теория по задаче

Задача направлена на понимание механизма наследования свойств и методов в JavaScript, а также различий между прямым наличием свойства и принадлежностью объекта этому свойству исключительно как собственному.

Прототипы в JavaScript

Прототипы являются основой системы наследования в JavaScript. Каждое создаваемое в JavaScript объект обладает ссылкой на прототип (__proto__), который представляет собой ещё один объект, содержащий дополнительные свойства и методы. Когда мы пытаемся обратиться к какому-либо свойству объекта, интерпретатор сначала ищет это свойство в самом объекте. Если оно там не обнаружено, процесс продолжается вверх по цепочке прототипов, пока свойство не будет найдено или достигнута вершина иерархии (обычно это пустой объект Object.prototype).

Например, стандартная конструкция объекта автоматически наследует общие методы вроде toString(), valueOf() и прочие, благодаря чему любое простое объявление объекта получает функциональность базовых операций, присущих объектам JavaScript.

Операторы и методы

  1. Оператор in Этот оператор проверяет наличие указанного свойства как в самом объекте, так и в его прототипах. Если свойство присутствует где-то в цепочке наследования, результатом проверки будет true. Таким образом, 'foo' in object возвращает true, поскольку свойство определено в самом объекте, а 'toString' in object также возвращает true, несмотря на отсутствие прямого объявления, потому что toString является методом базового прототипа (Object.prototype).
  2. Метод hasOwnProperty() Данный метод предназначен для проверки наличия конкретного свойства исключительно у самого объекта, игнорируя цепочку прототипов. Это означает, что если свойство объявлено самим объектом, метод вернет true, иначе — false. Свойство 'foo' определено нашим объектом, поэтому object.hasOwnProperty('foo') вернет true. Однако свойство 'toString' приходит из прототипа, поэтому object.hasOwnProperty('toString') вернет false.

Цепочка прототипов

Каждый объект имеет свою собственную цепочку прототипов, начинающуюся с непосредственного родителя-прототипа и заканчивающуюся верхним уровнем прототипа (Object.prototype). Именно такая структура позволяет нам обращаться к общим методам и свойствам без явного их переопределения в каждом отдельном объекте.

Итого

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